<!--添加ribbon的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency>
再要使用的 studyuser 工程下 添加配置类 ,引入 @LoadBalanced
@Configuration public class RestConfig { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
import org.springframework.web.client.RestTemplate; @RestController @RequestMapping("/user") @Slf4j public class UserController { @Autowired private RestTemplate restTemplate; @GetMapping("/findOrderByUserId/{id}") public R findOrderByUserId(@PathVariable("id")Integer id){ // 添加@LoadBalanced String url = "http://order-server/order/findOrderByUserId/" + id; R result = restTemplate.getForObject(url, R.class); return result } }
返回数据是该用户的订单信息
Spring Cloud Ribbon是基于Netflix Ribbon 实现的一套客户端的负载均衡工具,Ribbon客户端组件提供一系列的完善的配置,如超时,重试等。通过Load Balancer获取到服务提供的所有机器实例,Ribbon会自动基于某种规则(轮询,随机)去调用这些服务。Ribbon也可以实现我们自己的负载均衡算法。
ribbon 其他配置
修改默认负载均衡策略
ribbon 负载均衡策略配置
在 studyuser 项目添加如下配置
package com.jiuge.user.config; import com.alibaba.cloud.nacos.ribbon.NacosRule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RibbonConfig { /** * 全局配置 * 指定负载均衡策略 * @return */ @Bean public NacosRule IRule(){ // 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机权重) return new NacosRule(); } }
在 yml 里面加上
order-server: ribbon: # 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机&权重) NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
启动服务测试下
会出现如下输出
2021-08-04 10:32:03.002 INFO 12764 --- [nio-8010-exec-1] c.netflix.loadbalancer.BaseLoadBalancer : Client: order-server instantiated a LoadBalancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=order-server,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null 2021-08-04 10:32:03.012 INFO 12764 --- [nio-8010-exec-1] c.n.l.DynamicServerListLoadBalancer : Using serverListUpdater PollingServerListUpdater 2021-08-04 10:32:03.054 INFO 12764 --- [nio-8010-exec-1] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client order-server initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=order-server,current list of Servers=[192.168.2.73:8020],Load balancer stats=Zone stats: {unknown=[Zone:unknown; Instance count:1; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;] },Server stats: [[Server:192.168.2.73:8020; Zone:UNKNOWN; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0] ]}ServerList:com.alibaba.cloud.nacos.ribbon.NacosServerList@1cd5336d
说明配置生效。
自定义负载均衡
在 studyuser 项目中 添加自定义类 NacosRandomWithWeightRule 继承 AbstractLoadBalancerRule
package com.jiuge.user.rule; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; import com.alibaba.cloud.nacos.ribbon.NacosServer; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.pojo.Instance; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.loadbalancer.DynamicServerListLoadBalancer; import com.netflix.loadbalancer.Server; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; /** * @author jiuge * @version 1.0 * @date 2021/8/4 10:34 */ @Slf4j public class NacosRandomWithWeightRule extends AbstractLoadBalancerRule { @Autowired private NacosDiscoveryProperties nacosDiscoveryProperties; @Override public void initWithNiwsConfig(IClientConfig iClientConfig) { } @Override public Server choose(Object o) { DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer(); String serviceName = loadBalancer.getName(); log.info("serviceName == {}", serviceName); NamingService namingService = nacosDiscoveryProperties.namingServiceInstance(); try { // nacos 基于权重的算法 Instance instance = namingService.selectOneHealthyInstance(serviceName); return new NacosServer(instance); } catch (NacosException e) { log.error("获取服务实例异常:{}", e.getMessage()); e.printStackTrace(); } return null; } }
修改rule config配置bean
@Bean public IRule ribbonRule(){ return new NacosRandomWithWeightRule(); }
修改yml 中定义的负载均衡类
order-server: ribbon: # 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机&权重) # NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule NFLoadBalancerRuleClassName: com.jiuge.user.rule.NacosRandomWithWeightRule
输出的结果为
2021-08-04 10:52:13.886 INFO 8036 --- [nio-8010-exec-1] c.jiuge.user.controller.UserController : 根据userId:1查询订单信息 2021-08-04 10:52:14.236 INFO 8036 --- [nio-8010-exec-1] c.netflix.loadbalancer.BaseLoadBalancer : Client: order-server instantiated a LoadBalancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=order-server,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null 2021-08-04 10:52:14.246 INFO 8036 --- [nio-8010-exec-1] c.n.l.DynamicServerListLoadBalancer : Using serverListUpdater PollingServerListUpdater 2021-08-04 10:52:14.283 INFO 8036 --- [nio-8010-exec-1] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client order-server initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=order-server,current list of Servers=[192.168.2.73:8020],Load balancer stats=Zone stats: {unknown=[Zone:unknown; Instance count:1; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;] },Server stats: [[Server:192.168.2.73:8020; Zone:UNKNOWN; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0] ]}ServerList:com.alibaba.cloud.nacos.ribbon.NacosServerList@6bf1a891 2021-08-04 10:52:14.311 INFO 8036 --- [nio-8010-exec-1] c.j.user.rule.NacosRandomWithWeightRule : serviceName == order-server
说明配置生效
饥饿加载
在进行服务调用的时候,如果网络情况不好,第一次调用会超时。
Ribbon默认懒加载,意味着只有在发起调用的时候才会创建客户端。
微服务上开启饥饿加载
ribbon: eager-load: # 配置order-server使用ribbon饥饿加载,多个使用逗号分隔 clients: order-server # 开启ribbon饥饿加载 enabled: true
测试接口, 第一次是稍微反应快点了
2021-08-04 11:04:09.032 INFO 2944 --- [n(1)-13.13.0.80] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2021-08-04 11:04:09.033 INFO 2944 --- [n(1)-13.13.0.80] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2021-08-04 11:04:09.055 INFO 2944 --- [n(1)-13.13.0.80] o.s.web.servlet.DispatcherServlet : Completed initialization in 22 ms 2021-08-04 11:04:40.622 INFO 2944 --- [nio-8010-exec-1] c.jiuge.user.controller.UserController : 根据userId:2查询订单信息 2021-08-04 11:04:40.663 INFO 2944 --- [nio-8010-exec-1] c.j.user.rule.NacosRandomWithWeightRule : serviceName == order-server