Eureka服务注册与发现
Spring cloud 封装了 netfix 公司 Enruka 模块来进行服务治理。
什么是rpc 远程调用。 简单的理解的一个节点请求另外一个节点提供服务。
enruka 2个组件:Enruka server: 提供服务注册服务
Eruka client: 通过注册中心进行访问
搭建eureka 注册中心集群。实现负载均衡 + 故障容错
<dependencies> <!--eureka-server--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <!-- 引入自己定义的api通用包,可以使用Payment支付Entity --> <!--boot web actuator--> <!--监控--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--一般通用配置--> <!--热部署--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com
client:
# false 表示不向注册中心注册自己
register-with-eureka: false
# 表示自己端就是注册中心 我的职责就是服务实列 并不需要取检索服务
fetch-registry: false
service-url:
defaultZone: http://eureka7002.com:7002/eureka/
@EnableEurekaServer @SpringBootApplication @Slf4j public class EurekaMain7001 { public static void main(String[] args) { SpringApplication.run(EurekaMain7001.class,args); log.info("************ EurekaMain7001 服务启动 ************"); } }
@Autowired private RestTemplate restTemplate; private final String PAYMENT_URL = "http://localhost:8001/payment"; private final String PAYMENT_SERVICE = "CLOUD-PAYMENT-SERVICE"; @Autowired LoadBalancerClient loadBalancerClient; /** * 服务发现 获取服务器信息 */ @Autowired private DiscoveryClient discoveryClient;
@GetMapping("/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
List<ServiceInstance> instances = discoveryClient.getInstances(PAYMENT_SERVICE);
URI uri = null;
for (ServiceInstance instance : instances) {
uri = instance.getUri();
if (uri != null){
break;
}
}
ResponseEntity<CommonResult> entity = restTemplate.getForEntity(uri + "/payment/get/" + id, CommonResult.class);
if(entity.getStatusCode().is2xxSuccessful()){
return entity.getBody();
}else {
return new CommonResult<>(444,"失败");
}
}
@GetMapping("/consumer/payment/lb2")
public String getServerPort2(){
ServiceInstance choose = loadBalancerClient.choose(PAYMENT_SERVICE);
return restTemplate.getForObject(choose.getUri() + "/payment/lb",String.class);
}
工具类discoveryClient可以根据服务名获取对应服务地址列表。
LoadBalancerClient先从提供的服务中获取某一个实例(默认策略为轮询),比如订单服务需要访问商品服务,
商品服务有3个节点,LoadBalancerClient会通过choose(),方法获取到3个节点中的一个服务,
拿到服务的信息之后取出服务ip信息,就可以得到完成的想要访问的ip地址和接口,最后通过RestTempate访问商品服务。