Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP客户端行为。为Ribbon配置服务提供者地址列表后,Ribbon就可以基于某种负载均衡算法,自动地帮助服务消费者去提供请求。
在springcloud中,当Ribbon配合Eureka使用时,Ribbon可自动从Eureka Server获取服务提供者的地址列表,并基于某种负载均衡算法,请求其中第一个服务提供者实例,常用的算法有随机规则和轮询,当没有指定规则时,默认使用的算法为轮询。
下面来演示实怎么用Ribbon结合Eureka实现负载均衡:
现准备一个eureka注册中心,2个名为expense的服务,均为服务的提供者(provider),服务除了端口不一样,其他都保持一致,1个payment服务,在案例中当消费者(consumer)。
各服务使用的springcloud版本为:
1.8
Greenwich.SR4
springboot版本为:
org.springframework.boot
spring-boot-starter-parent
2.1.11.RELEASE
客户端的依赖和配置文件如下:
payment服务:
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.11.RELEASE
com.example.hand
payment
0.0.1-SNAPSHOT
payment
project for Spring Boot
1.8
Greenwich.SR4
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-security
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
applicantion.properites配置文件:
server.port=9098
spring.application.name=payment
eureka.instance.prefer-ip-address=true
eureka.instance.instance-id=192.168.3.25:9098
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.instance.lease-renewal-interval-in-seconds =100
eureka.instance.lease-expiration-duration-in-seconds =50
spring.security.user.name=user
spring.security.user.password=user123
provider.name1=expense
另外一个拥有2个实例的expense服务的pom.xml文件:
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.11.RELEASE
com.example.hand
expense
0.0.1-SNAPSHOT
expense
project for Spring Boot
1.8
Greenwich.SR4
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
com.example.hand.Expense1Application
application.properties文件 :
端口为9096的:
server.port=9096
spring.application.name=expense
eureka.instance.prefer-ip-address=true
eureka.instance.instance-id=192.168.2.13:9096
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.instance.lease-renewal-interval-in-seconds =30
eureka.instance.lease-expiration-duration-in-seconds =30
端口为9097的:
server.port=9097
spring.application.name=expense
eureka.instance.prefer-ip-address=true
eureka.instance.instance-id=192.168.2.13:9097
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.instance.lease-renewal-interval-in-seconds =30
eureka.instance.lease-expiration-duration-in-seconds =30
所需要的配置添加好以后,如果有远程调用,需要在消费者端,启动类添加如下代码,将远程调用RestTemplate类交给spring容器管理初始化,到后面我们要用的时候直接使用@Autowire注解就可以了,然后添加@LoadBanlanced注解,Ribbon客户端请求服务端就有负载均衡的效果:
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
补充一点:介绍通过打jar包的形式,使用java命令来发布2个同名的实例。在expense服务下启动两个终端,分别使用不同端口号来启动:
第一步,在pom文件中添加
com.example.hand
expense
0.0.1-SNAPSHOT
jar
expense
然后使用命令: mvn install
执行完成后,会在target目录下生成一个后缀为.jar的文件,和.jar.original文件:
然后分别使用9096端口和9097端口执行命令,如下默认使用的配置文件中的默认端口启动:
java -jar expense-0.0.1-SNAPSHOT.jar
修改expense的实例id,在修改配置文件后,重新打jar包,修改实例的id和端口号后再启动:
java -jar expense-0.0.1-SNAPSHOT.jar --server.port=9097
切换到指定的目录下:
启动后:
启动各服务,效果如下:
然后在客户端定义一个接口使用loadBalancerClient去调用主机名为expense的服务,Ribbon客户端会根据eureka里面的服务器的地址列表来轮询选择一个实例进行请求!
Payment的java代码如下:
@GetMapping("/get/instance")
public String getInstance(){
ServiceInstance instance=this.loadBalancerClient.choose("expense");
String str="实例的id为:"+instance.getServiceId()+",实例的域名为:"+instance.getHost()+",端口为:"+instance.getPort();
LOGGER.info(str);
return str;
}
然后访问如下Url:http://localhost:9098/api/wallet/get/instance
刷新页面后,会发现返回的结果为在9097和9096之间来回切换:
控制台打印结果如下:
由上述结果发现,这样就实现负载均衡了,默认的负载均衡规则为轮询,在2各节点之间来回切换!