SpringCloud2
1.上一篇存在的问题
- 1.consumer中url硬编码,不方便维护
- consumer需要记忆user-service的地址,如果变更访问失败
- consumer不清除user-service的状态,服务是否宕机
- user-service只有一台服务,不具备高可用性
- 即便有多个user-service,还得实现负载均衡
总结 - 服务管理
- 如何自动注册和发现
- 如何实现状态监管
- 如何实现动态路由
- 服务如何实现负载均衡
- 服务如何解决容灾问题
- 服务如何实现统一配置
2.Eureka注册中心
Eureka就像是滴滴打车,服务是出租车,如果出租车需要出租,首先要在滴滴上注册,注册要执行的服务以及出租车各种信息。
- Eureka:就是服务注册中心(可以是一个集群),对外暴露自己的地址
- 提供者:启动后向Eureka注册自己信息(地址,提供什么服务)
- 消费者:向Eureka订阅服务,Eureka会将对应服务的所有的提供者地址列表发送给消费者,并且定期更新
- 心跳(续约):提供者定期通过http方式向Eureka刷新自己的状态
3.项目编写
ps:在上一篇的代码基础上实现
一.Eureka编写
1.创建新Module名为eureka-server
2.添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<!--这里不需要写版本号,父工程以及统一对SpringCloud进行管理了-->
</dependency>
//依赖语句将Eureka的注册实现功能都给实现了,所有不用再编写实现
3.编写启动器
@EnableEurekaServer
@SpringBootApplication
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class);
}
}
4.编写application.yaml修改tomcat端口
server:
port: 10086
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka #告诉它注册的地址key-value,默认是localhost:8761末尾一定是写/eureka
spring:
application:
name: eureka-server #给Eureka的名称
ps:#是yaml文件的注释符号
启动eureka-server
参数细节描述
二.user-service服务端注册Eureka编写
1.上一章节已经编写过的user-service项目需要添加Eureka客户端依赖
<!--Eureka的客户端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.再给user-service启动器添加Eureka注解
添加@EnableDiscoveryClient
为什么不用@EnableEurekaClient注解呢? 原因是上面这个注解不仅可以用在Eureka上也能用在zookeeper上等等。
3.再给user-service工程修改yaml
- 1.添加应用启动名字
- 2.添加Eureka配置
三.consumer-demo调用方编写
1.引依赖
添加
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.加注解
3.给consumer-demo添加application.yaml配置
server:
port: 8088
spring:
application:
name: consumer-service
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
4.Consumer动态获取服务列表
重新修改consumer-demo下的web包里面的ConsumerController.class
修改的地方
package com.tutu.consumer.web;
import com.tutu.consumer.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RequestMapping("consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("{id}")
public User queryById(@PathVariable("id") Long id){
//user-service是之前在yaml配置的名字,可以同一个服务,启动多个,后面负载均衡要用所以用List集合
List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
//从实例当中取出ip和端口
ServiceInstance instance = instances.get(0); //这个地方以后要自己写动态获取服务算法
String url = "http://"+instance.getHost()+":"+instance.getPort()+"/user/"+id;
User user = restTemplate.getForObject(url,User.class);
return user;
}
}
5.结果
1.启动三个项目
2.输入:localhost:10086
查看是否如下
最后网页输入:
看看是否能返回结果。
源码地址:github源码