Spring Cloud为开发人员提供了工具,以快速构建分布式系统中的某些常见模式(例如,配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,领导选举,分布式会话,群集状态)。分布式系统的协调导致样板式样,并且使用Spring Cloud开发人员可以快速站起来实现这些样板的服务和应用程序。它们可以在任何分布式环境中正常工作,包括开发人员自己的笔记本电脑,裸机数据中心以及Cloud Foundry等托管平台。
特征
Spring Cloud专注于为典型的用例和可扩展性机制(包括其他用例)提供良好的开箱即用体验。
-
分布式/版本化配置
-
服务注册和发现
-
路由
-
服务到服务的呼叫
-
负载均衡
-
断路器
-
全局锁
-
领导选举和集群状态
-
分布式消息传递
Eureka
云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移。
通过配置文件多集群搭建
在 application.properties 中指定要加载的配置文件
#加载的配置文件,配置文件必须以 application- 开头,值为- 后面的值
spring.profiles.active=eur8100
这里创建了三个,分别是 application-eur8100.properties、application-eur8200.properties、application-eur8300.properties
通过指定,来加载不同的配置文件。
注意:需要去掉pom 中的 dev-tool 依赖,不然修改配置文件造成热部署。
eureka.server.enable-self-preservation 参数
#关闭自我保护
# 设置 false 时,页面会提示:THE SELF PRESERVATION MODE IS TURNED OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
eureka.server.enable-self-preservation=false
该参数设置为 true就不会出现下面这种了
配置文件:
application.properties
#加载的配置文件,配置文件必须以 application- 开头,值为- 后面的值
spring.profiles.active=eur8100
application-eur8100.properties
#是否将自己注册到Eureka Server,默认为true,由于当前就是server,故而设置成false,表明该服务不会向eureka注册自己的信息
# 为 true 的话 在页面的 Instances currently registered with Eureka 里面可以看到自己
eureka.client.register-with-eureka=true
#对应的服务器未启动或异常时,会出现 unavailable-replicas
#设置服务注册中心的URL,用于client 和server端交流
# 服务器名+端口号 : eureka.instance.hostname + server.port/eureka
#eureka.client.service-url.defaultZone=http://eureka1.com:8101/eureka
# 向第二台服务器注册
eureka.client.service-url.defaultZone=http://eureka1.com:8101/eureka,http://eureka3.com:8301/eureka,http://eureka1.com:8101/eureka
#是否从eureka server获取注册信息,由于单节点,不需要同步其他节点数据,用false
eureka.client.fetch-registry=false
#设置服务注册中心的URL,用于client和server端交流
#关闭自我保护
# 设置 false 时,页面会提示:THE SELF PRESERVATION MODE IS TURNED OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
eureka.server.enable-self-preservation=false
#名字必须一样,才能被认为是同一个集群的
spring.application.name=EurekaServer
#tomcat 端口
server.port=8101
#服务器主机名
eureka.instance.hostname=eureka1.com
eureka.instance.instance-id=eureka-8100
eureka.instance.metadata-map.dalao=malaoshi
#安全认证
#spring.security.user.name=yiming
#spring.security.user.password=123
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
#spring.boot.admin.client.url=http://localhost:8080
application-eur8200.properties
#是否将自己注册到Eureka Server,默认为true,由于当前就是server,故而设置成false,表明该服务不会向eureka注册自己的信息
eureka.client.register-with-eureka=true
#是否从eureka server获取注册信息,由于单节点,不需要同步其他节点数据,用false
eureka.client.fetch-registry=false
#设置服务注册中心的URL,用于client和server端交流
server.port=8201
#服务器主机名
eureka.instance.hostname=eureka2.com
eureka.instance.instance-id=eureka-8200
spring.application.name=EurekaServer
eureka.instance.metadata-map.dalao=malaoshi
#设置服务注册中心的URL,用于client 和server端交流 自己的
#eureka.client.service-url.defaultZone=http://eureka2.com:8201/eureka
#别人的
eureka.client.service-url.defaultZone=http://eureka1.com:8101/eureka,http://eureka3.com:8301/eureka,http://eureka1.com:8101/eureka
#安全认证
#spring.security.user.name=yiming
#spring.security.user.password=123
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
#spring.boot.admin.client.url=http://localhost:8080
启动多个spring boot 就可以了。如果不会启动多个的,可以按照下面
Renew
续租,心跳
eureka 客户端需要每30秒发送一次心跳来续租,告诉服务端自己还活着。
Fetch Registry
eureka 客户端从服务器获取注册表信息并将其缓存到本地,之后,客户端使用这些信息来查找其它服务。
通过获取上一个获取周期和当前获取周期之间的增量更新,每30秒更新信息。
新建一个client
浏览器输入 eureka.client.service-url.defaultZone=http://eureka1.com:8101/eureka 配置文件后面的 http://eureka1.com:8101/eureka/apps 可以查看到相关信息。注意是server地址哦
获取服务相关信息以及服务相关url
传入的 Instances 参数为 配置的 spring.application.name 值
@Autowired
DiscoveryClient client;
@GetMapping("/client")
String client(){
List<String> services = client.getServices();
System.out.println(ToStringBuilder.reflectionToString(services));
StringBuilder bud = new StringBuilder();
for (String s : services) {
bud.append("<br/>").append(s);
}
return bud.toString();
}
@GetMapping("/ins")
Object services(){
List<String> services = client.getServices();
System.out.println(ToStringBuilder.reflectionToString(services));
StringBuilder bud = new StringBuilder();
for (String s : services) {
List<ServiceInstance> instances = client.getInstances(s);
bud.append("<br>" + s + ": ").append(s);
for(ServiceInstance ser : instances) {
bud.append("<br/> ").append(ser.getUri() + " "
+ ser.getHost() + ":" + ser.getPort());
}
}
return bud.toString();
}
结果:
获取服务具体服务信息
@GetMapping("/insBy")
Object insBy(String by){
return client.getInstances(by);
}