项目结构
主项目maven依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>0.2.2.RELEASE</version> </dependency> </dependencies>
|
会员服务(生产者)
服务接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @RestController public class MemberService { @Value("${server.port}") private String serverPort;
@RequestMapping("/getUser") public String getUser(Integer userId) { return "hello nacos,端口号:" + serverPort; } }
|
配置文件
1 2 3 4 5 6 7 8 9 10
| spring: application: name: tinner-member cloud: nacos: discovery: server-addr: 127.0.0.1:8848 server: port: 8081
|
注意:
在这里我直接使用负载均衡进行调用了,所以要启动两个服务来模拟实现集群(修改端口号),关于idea中支持一套代码启动两个服务的设置:
订单服务(消费者)
订单调用会员服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
@RestController public class OrderController {
@Autowired private DiscoveryClient discoveryClient;
@Autowired private RestTemplate restTemplate;
@Autowired private LoadBalancer loadBalancer;
@GetMapping("/orderToMember") public Object orderToMember(){ List<ServiceInstance> instances = discoveryClient.getInstances("tinner-member");
ServiceInstance singleAddress = loadBalancer.getSingleAddress(instances); String result = restTemplate.getForObject(singleAddress.getUri() + "/getUser", String.class); return "订单调用会员返回结果:"+ result; } }
|
负载均衡算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public interface LoadBalancer {
ServiceInstance getSingleAddress(List<ServiceInstance> serviceInstanceList);
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
@Component public class RotationLoadBalancer implements LoadBalancer {
private AtomicInteger requireNum = new AtomicInteger(0);
@Override public ServiceInstance getSingleAddress(List<ServiceInstance> serviceInstanceList) { return serviceInstanceList.get(requireNum.incrementAndGet() % serviceInstanceList.size()); } }
|
运行效果
1、分别以8080、8081端口启动两个tinner-member服务,可以看到在nacos控制台中注册了两个tinner-member
服务
2、启动order服务,调用order的接口,多次调用,可以依次看到轮询访问
tinner-member
服务
3、如果在控制台中将某个节点下掉,由于轮询的时候是动态获取服务列表的,所以对于调用方并没有感知,依旧能为order提供服务