前言
本文是根據螞蟻課堂余勝軍老師的課程所做筆記,記錄的要點,部分自己的理解可能有所偏差,不當之處會進行修改。
微服務服務治理核心概念
在微服務架構通訊中,服務之間依賴關系非常大,如果通過傳統的方式管理服務url地址,一旦地址發生變化,還需要人工修改rpc遠程調用地址。
所以采用服務url治理技術,治理的技術可以實現對我們的整個實現動態服務注冊與發現,本地負載均衡、容錯等。
分布式注冊中心實現原理
注冊中心實際上就是管理我們服務的url信息,能夠實現動態感知。
有Dubbo依賴Zookeeper、Eureka、Consul、Nacos
注冊中心就是將一個服務的服務id和其IP與端口號作為鍵值對存放到注冊中心,通過服務id可以找到IP地址和端口號。
另一個服務通過注冊中心獲取到該服務的ip和端口號后,在本地實現rpc調用。
服務名對應的ip地址是一個列表,通過負載均衡算法取出一個地址調用。
Nacos基本介紹
Nacos 提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務元數據及流量管理。
下載nacos,解壓后直接運行bin目錄下的start腳本即可
在Linux下使用下面命令代表非集群運行
sh startup.sh -m standalone
默認用8848端口啟動,在ip:8848/nacos進入管理面板,默認賬號密碼都是nacos
服務注冊
創建一個會員項目
導入依賴
<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>
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
</dependencies>
配置文件
spring:
application:
name: member-nacos #服務名
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #注冊中心地址
創建一個服務
@RestController
public class UserService {
@GetMapping("/user")
public String getUser() {
return "alibaba-nacos-test";
}
}
啟動項目
如果使用的是eureka,還需要使用注解@EnableEurekaServer開啟服務注冊,但是使用nacos,直接啟動項目就能注冊服務。
使用discoveryClient從注冊中心獲取接口地址
創建一個訂單項目
配置文件與會員項目相同,更改一下端口號。
創建服務調用會員服務
@RestController
public class OrderService {
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/orderToMember")
public Object orderToMember() {
//通過服務名獲取接口地址
List<ServiceInstance> instances = discoveryClient.getInstances("member-nacos");
return instances.get(0);
}
}
使用restTemplate實現RPC遠程調用
項目中並沒有注冊restTemplate,需要手動注冊一個。
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
實現調用
@RestController
public class OrderService {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
@GetMapping("/orderToMember")
public Object orderToMember() {
//通過服務名獲取接口地址
List<ServiceInstance> instances = discoveryClient.getInstances("member-nacos");
ServiceInstance serviceInstance = instances.get(0);
//通過服務地址加上方法名調用,String.class為方法返回值類型
String object = restTemplate.getForObject(serviceInstance.getUri() + "/user", String.class);
return "調用返回結果"+object;
}
}
手寫負載均衡輪詢算法
通常從注冊中心獲取到的服務是集群列表,使用負載均衡來選擇一個服務調用。
負載均衡的算法有:一致性hash計算、輪詢、權重、隨機
可以用策略模式,來實現不同的算法。這里我們實現輪詢算法
創建一個接口
public interface LoadBalancer {
ServiceInstance getOneService(List<ServiceInstance> serviceInstances);
}
實現輪詢算法
@Component
public class RotationLoadBalancer implements LoadBalancer {
private AtomicInteger atomicInteger = new AtomicInteger(0);
@Override
public ServiceInstance getOneService(List<ServiceInstance> serviceInstances) {
int index = atomicInteger.incrementAndGet()%serviceInstances.size();
return serviceInstances.get(index);
}
}