我们之前的 Spring Cloud 服务采用的都是 单节点 ,一个是因为想简单的给大家演示整个 Spring Cloud 的架构思路,另外一个是微服务确实挺占用服务器的,尤其是生产环境上,不可预测的因素会很多,都要求我们整个服务是高性能,高并发,高可用的,所以集群就扮演了一个很重要的角色。从我们这些项目来看,服务发现与注册中心,配置中心,网关中心都是比较重要的环节,单节点架构环境下,只要一个挂了就会影响绝大部分的业务。我们使用的是 Eureka ,先看看它是怎么样来实现 Eureka 集群 的,需要注意的是,我用的windows的开发环境,来开始改造我们 Eureka 服务端 。
由于资源问题,我这里就规划三台 Eureka服务 。
| 服务器IP地址 | 主机名 | 端口 |
|---|---|---|
| 10.130.3.111 | eureka-server1.com | 8761 |
| 10.130.3.222 | eureka-server2.com | 8761 |
| 10.130.3.66 | eureka-server3.com | 8761 |
接下里就在服务 10.130.3.111 、 10.130.3.222 和 10.130.3.66 上分别修改hosts文件( 记得是部署Eureka服务的机器哦),具体的路径是: C:\Windows\System32\drivers\etc\hosts (可以使用Notepad++修改)
#Eureka要为域名形式
10.130.3.111 eureka-server1.com
10.130.3.222 eureka-server2.com
10.130.3.66 eureka-server3.com
这里需要注意的是本文是要配置 Eureka的实例的主机名 , defaultZone 中是以域名的方式向注册中心注册的,所以这里需要使用域名。后面我也会讲怎么使用 IP 的方式进行集群。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>cn.alian.microservicegroupId>
<artifactId>parentartifactId>
<version>1.0.0-SNAPSHOTversion>
parent>
<artifactId>discovery-serviceartifactId>
<version>1.0.0-SNAPSHOTversion>
<packaging>jarpackaging>
<name>discovery-servicename>
<description>服务注册与发现之集群description>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
dependencies>
project>
和单节点一样,也没有什么变化。
DiscoveryApplication.java
package cn.alian.microservice.discovery;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class DiscoveryApplication {
public static void main(String[] args) {
SpringApplication.run(DiscoveryApplication.class, args);
}
}
和单节点一样,也没有什么变化。
application.properties
#服务名
spring.application.name=discovery-service
#端口
server.port=8761
#实例名称
eureka.instance.hostname=eureka-server1.com
#为true时使用ip而不是主机名,这里必须使用主机名
eureka.instance.ip-address=false
#服务1注册到服务2和服务3中
eureka.client.service-url.defaultZone=http://eureka-server2.com:8762/eureka,http://eureka-server3.com:8763/eureka
#连接Eureka Server的超时时间,单位:秒
eureka.client.eureka-server-connect-timeout-seconds=20
#用于指示Eureka客户端已启用的标志
eureka.client.enabled=true
#客户端是否获取eureka服务器注册表上的注册信息,默认为true
eureka.client.fetch-registry=true
#指示此实例是否应将其信息注册到eureka服务器以供其他服务发现,默认为false
eureka.client.register-with-eureka=true
#启用自我保护机制,默认为true,
#为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
# eureka的阈值(默认值)是0.85(当注册在eureka中的正常服务占比低于85%时会开启eureka的自我保护)
# 也就是说Eureka Server在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期
#每分钟需要收到的续约次数阈值(心跳数/client实例数)
eureka.server.renewal-percent-threshold=0.85
#清除无效服务实例的时间间隔(ms),默认1分钟
eureka.server.eviction-interval-timer-in-ms=30000
#是否从readonly(只读缓存)中读取实例(默认是true)
eureka.server.use-read-only-response-cache=false
#读超时时间
eureka.server.peer-node-read-timeout-ms=60000
#部署时配置加上
#logging.config=config/logback.xml
上面这个是 eureka-server1.com配置,另外两台服务的配置区别在于三个参数不同分别是:
eureka-server2.com对应的配置如下:
#端口
server.port=8762
#实例名称
eureka.instance.hostname=eureka-server2.com
#服务2注册到服务1和服务3中
eureka.client.service-url.defaultZone=http://eureka-server1.com:8761/eureka/,http://eureka-server3.com:8763/eureka/
eureka-server3.com对应的配置如下:
#端口
server.port=8763
#实例名称
eureka.instance.hostname=eureka-server3.com
#服务3注册到服务1和服务2中
eureka.client.service-url.defaultZone=http://eureka-server1.com:8761/eureka/,http://eureka-server2.com:8762/eureka/
最后需要注意的是 eureka.instance.hostname 的值要和我们配置到本机hosts的值要对应。然后就是任意一台 Eureka服务 ,都要注册其他 Eureka服务 上,不要只注册一台,因为这样达不到高可用,因为只注册一台,有可能刚好那台服务挂了。



从上面的效果图上来看,每个 Eureka 服务都注册到其他 Eureka 服务上了, DS Replicas 就是当前实例的副本,我们也可以看到每个服务上都有三个注册信息,并且也没有出现 unavailable-replicas ,这个是很关键的哦。
现在集群已经搭建好了,我们集群的地址就是三台 Eureka服务 的地址:
#eureka服务注册地址
eureka.client.serviceUrl.defaultZone=http://eureka-server1.com:8761/eureka/,http://eureka-server2.com:8762/eureka/,http://eureka-server3.com:8763/eureka/
假设我们有个新的支付系统,我们用最简单的方式注册进去,一起看看效果。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>cn.alian.microservicegroupId>
<artifactId>parentartifactId>
<version>1.0.0-SNAPSHOTversion>
parent>
<groupId>cn.alian.mallgroupId>
<artifactId>payartifactId>
<version>1.0.0-SNAPSHOTversion>
<name>payname>
<description>paydescription>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
dependencies>
project>
application.properties
#服务名
spring.application.name=pay
#端口
server.port=9001
#eureka服务注册地址
eureka.client.serviceUrl.defaultZone=http://eureka-server1.com:8761/eureka/,http://eureka-server2.com:8762/eureka/,http://eureka-server3.com:8763/eureka/
主类上加上注解: @EnableDiscoveryClient ,此类具体路径: org.springframework.cloud.client.discovery.EnableDiscoveryClient
package cn.alian.mall.pay;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class PayApplication {
public static void main(String[] args) {
SpringApplication.run(PayApplication.class, args);
}
}
我们再依次在浏览器请求:
结果如下:
