上一篇:spirngcloud alibaba初体验(1)–nacos
一、pom依赖
由于nacos-discovery中已经引入ribbon的jar包,所以我们无须引入
二、代码编写
1、配置restTemplate
// alibaba版本1.5.1之后@EnableDiscoveryClient注解可不用再加
// @EnableDiscoveryClient
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Bean
// 因为是url中我们写的服务名称,restTemplate无法识别,需要添加@LoadBalanced注解
// ribbon会从注册中心获取服务名称对应地址,轮询调用
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
}
2、注入restTemplate,并调用相关方法
@Service
public class OrderService {
@Autowired
private RestTemplate template;
public void create() {
String str = template.getForObject("http://stock-service/stock/deduct/5", String.class);
System.out.println("库存返回:" + str);
}
}
3、运行4次程序,结果如下,确认轮询访问
三、负载策略修改
1、已默认支持的负载实现
2、自定义负载策略
// 继承com.netflix.loadbalancer.AbstractLoadBalancerRule,重写choose方法
public class MyRule extends AbstractLoadBalancerRule {
private Random random = new Random();
public void initWithNiwsConfig(IClientConfig iClientConfig) {}
public Server choose(Object o) {
List<Server> servers = getLoadBalancer().getAllServers();
return servers.get(random.nextInt(servers.size()));
}
}
3、配置文件方式
stock-service: # nacos注册的服务名称
ribbon:
NFLoadBalancerRuleClassName: com.sinlan.order.config.MyRule
4、java Configuration方式
// alibaba版本1.5.1之后@EnableDiscoveryClient注解可不用再加
// @EnableDiscoveryClient
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Bean
// 因为是url中我们写的服务名称,restTemplate无法识别,需要添加@LoadBalanced注解
// ribbon会从注册中心获取服务名称对应地址,轮询调用
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
// 这种会被springboot扫描的,会对所有ribbon client生效
@Bean
public IRule ribbonRule() {
return new MyRule();
}
}
@SpringBootApplication
// 可配置多个ribbonclient
@RibbonClients({
// 针对服务名称为stock-service的使用MyRule负载策略
@RibbonClient(name = "stock-service", configuration = MyRule.class)
})
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Bean
// 因为是url中我们写的服务名称,restTemplate无法识别,需要添加@LoadBalanced注解
// ribbon会从注册中心获取服务名称对应地址,轮询调用
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
}
5、运行4次程序,结果如下,确认负载策略已经修改
四、负载均衡器替换
由于ribbon是Netflix公司的,目前已停止维护,Spring cloud官方提供了Sping cloud loadBanancer,用来代替Ribbon。
1、pom依赖
<!-- nacos注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<!-- 排除ribbon -->
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- LoadBalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
2、yaml配置禁用ribbon
spring:
cloud:
loadbalancer:
ribbon:
enabled: false # 不使用ribbon
3、启动程序,提示使用了Spring Cloud loadBalancer
4、自定义负载均衡策略
public class MyRule implements ReactorServiceInstanceLoadBalancer{
private Random random = new Random();
// 服务列表
private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
public MyRule(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider) {
this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
}
public Mono<Response<ServiceInstance>> choose(Request request) {
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider.getIfAvailable();
return supplier.get().next().map(this::getInstanceResponse);
}
private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
ServiceInstance instance = instances.get(random.nextInt(instances.size()));
return new DefaultResponse(instance);
}
}
@SpringBootApplication
// 可配置多个loadbalancer client
@LoadBalancerClients({
// 针对服务名称为stock-service的使用MyRule负载策略
@LoadBalancerClient(name = "stock-service", configuration = MyRule.class)
})
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Bean
// 因为是url中我们写的服务名称,restTemplate无法识别,需要添加@LoadBalanced注解
// ribbon会从注册中心获取服务名称对应地址,轮询调用
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
}