Eureka注册中心集群
为什么要集群
如果只有一个注册中心服务器,会存在单点故障,不可以高并发处理所以要集群。
如何集群
准备三个EurekaServer 相互注册,也就是说每个EurekaServer都需要向所有的EureakServer注册,包括自己 ,每个EurekaServer即充当了服务端,也充当了客户端。咱们的其他微服务(order,user)只需要把注册地址指向所有的EurekaServer就可以了。
代码实现:
此处采用的是一个Eureka模块,配置多份yml文件,达到集群的效果 。
启动类
java">package org.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;/*** @ClassName EurekaStart* @Author 23* @Date 2024/7/10 19:12* @Version 1.0* @Description TODO**/
@SpringBootApplication
@EnableEurekaServer
public class EurekaStart {public static void main(String[] args) {SpringApplication.run(EurekaStart.class,args);}
}
yml
spring:profiles:active: peer3
---
spring:profiles: peer1application:name: Eureka1
eureka:instance:hostname: localhostclient:serviceUrl:defaultZone: http://localhost:10070/eureka/
server:port: 10070
---
spring:profiles: peer2application:name: Eureka2
eureka:instance:hostname: localhostclient:serviceUrl:defaultZone: http://localhost:10071/eureka/
server:port: 10071
---
spring:profiles: peer3application:name: Eureka3
eureka:instance:hostname: localhostclient:serviceUrl:defaultZone: http://localhost:10072/eureka/
server:port: 10072
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.example</groupId><artifactId>Springcloud-Netflix</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>Eureka-Service</artifactId><packaging>jar</packaging><name>Eureka-Service</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><!-- Eureka服务端支持 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies>
</project>
服务负载均衡
为什么需要负载均衡
为了提供并发量,有时同一个服务提供者可以部署多个(商品服务)。这个客户端在调用时要根据一定的负责均衡策略完成负载调用。
服务提供者配置
spring:profiles:active: order2
---
server:port: 10010
spring:profiles: order1application:name: order-service
eureka:client:service-url:defaultZone: http://localhost:10072/eurekainstance:prefer-ip-address: true
---
server:port: 10012
spring:profiles: order2application:name: order-service
eureka:client:service-url:defaultZone: http://localhost:10072/eurekainstance:prefer-ip-address: true
常见的负载均衡实现技术
Ribbon
通过RestTmplate,以url完成服务的调用
代码实现(服务消费端):
java">package org.example.Controller;import org.example.domain.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import java.util.Arrays;
import java.util.List;/*** @ClassName UserController* @Author 23* @Date 2024/7/10 18:52* @Version 1.0* @Description TODO**/
@RestController
@RequestMapping("/User")
public class UserControllerrlb {@Autowiredprivate RestTemplate restTemplate;
// @Autowired
// private DiscoveryClient discoveryClient;@GetMapping("/getOrder/{id}")public List<Order> getOrderById(@PathVariable("id") Integer id) {
// Order[] order = restTemplate.getForObject("http://localhost:10010/OrderService/user/" + id, Order[].class);
// return Arrays.asList(order);
// List<ServiceInstance> instances=discoveryClient.getInstances("order-service");//通过服务的名字去获取服务实例
// ServiceInstance serviceInstance=instances.get(0);//定死只获取第一个服务实例对象
// String ip=serviceInstance.getHost();//获取服务对象ip
// int port=serviceInstance.getPort();//获取获取的实例对象的服务端口号Order[] orders=restTemplate.getForObject("http://Order-Service/OrderService/user/"+id,Order[].class);return Arrays.asList(orders);}
}
Ribbon负载均衡调用
Ribbon是Netflix发布的云中间层服务开源项目,主要功能是提供客户端负载均衡算法。Ribbon客户端组件提供一系列完善的配置项,如,连接超时,重试等。简单的说,Ribbon是一个客户端负载均衡器,我们可以在配置文件中列出load Balancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。Ribbon是一个客户端负载均衡器,它可以按照一定规则来完成一种服务多个服务实例负载均衡调用,这些规则还支持自定义。
原理图:
OpenFeign负载均衡
OpenFeign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。Feign提供了HTTP请求的接口模板(上面标的有访问地址),通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。而OpenFeign则会完全代理(动态代理)HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon和Hystrix(关于Hystrix我们后面再讲),可以让我们不再需要显式地使用这两个组件。
负载均衡策略
IRule
通过配置不同IRule的子类,可以选择不同负载均衡策略,也就是从服务列表以特定策略选择一个服务来完成调用。当然也可以自定义。所以负载均衡策略可以分为内置和自定义。
内置负载均衡策略