SpringCloud笔记三:Eureka服务注册与发现
什么是Eureka?
Eureka是一个服务的注册中心,有服务端和客户端。我举个栗子。
一个大型商场新建完毕,各种商家开始准备入住。需要的流程是:
- 商家去大型商场注册,交费,签合同
- 熙熙攘攘的人群在大型商场门口的导航牌看哪个店在几楼,然后去消费
在这个例子中,Eureka就是大型商场,就是一个服务中心。加了服务端注解@EnableEurekaServer之后就可以开启服务中心了,然后商家就是客户端,要加@EnableEurekaClient之后就可以去注册了。至于消费者,直接去消费
Eureka注册的三大步
第一步,引用Maven
想要使用Eureka,先引用Maven,服务端和客户端不一样
服务端:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
客户端:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
必须要加版本号,不然第三步的注解不能生效的
第二步,配置yml
我们需要配置yml文件,告诉系统,服务端的Eureka调用地址是什么,客户端的Eureka访问地址是什么
服务端:
server:
port: 7001
eureka:
instance:
hostname: localhost #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
服务器端基本就是这样写的,没什么需要改的
客户端:
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://localhost:7001/eureka
instance:
instance-id: provider-8001 #这个是修改Eureka界面的Status名称
prefer-ip-address: true #这个是设置鼠标放在status上的时候,出现的提示,设置ip地址显示
客户端的defaultZone是Eureka的注册中心的地址,这个是在服务端写的,服务端怎么写,这里就怎么写。
instance-id这个是Eureka页面的status的名称
prefer-ip-address这个是鼠标放在status上的时候显示的内容,把ip地址显示出来。
这里的具体,在第四步,我会截图。
第三步,开启Eureka注解
开启注解,告诉我的子项目,你有权限使用Eureka注册服务了,Maven已经下载了,yml也告诉你访问路径了,去使用它吧,在子系统的主方法上加就ok
服务端:
@EnableEurekaServer
客户端:
@EnableEurekaClient
新建Eureka子项目
我们来新建一个子项目,还是一样的,我起名为Eureka-7001 。我们需要在yml里面写上面的服务端的内容。然后在项目的主方法上加上@EnableEurekaServer注解。至此,加了服务端yml和注解的Eureka-7001项目就是服务中心了。
现在可以运行了,很简单,首先我们先运行Eureka-7001这个子工程
可以看到,我们的Eureka服务中心已经跑起来了,但是目前,还没有任何一个客户端来注册啊。商家呢?快来注册交费入驻。
把provider子项目变成服务端
我们要把provider项目改为Eureka的客户端,并且注册进我们的服务中心。
- 先改provider项目的yml,还是上面讲的客户端yml就是,复制
- 主方法加@EnableEurekaClient注解
这个时候,保持Eureka-7001服务中心运行的同时,我们再启动provider项目,你会发现
由于我上面客户端的yml写的
instance:
instance-id: provider-8001 #这个是修改Eureka界面的Status名称
prefer-ip-address: true #这个是设置鼠标放在status上的时候,出现的提示,设置ip地址显示
正是由于写了上面的这俩,所以我的图中的status就是我自己定义的,以及鼠标放上去时,左下角显示的内容,才会有ip显示出来。
最后,你点击status下面的名称试试,会出现一个info页面,不过是没啥内容的。我们希望,点击微服务的status的时候,可以显示出这个微服务的一些信息,比如版本号,公司名称。我们需要两步
- 在主工程加如下代码,这个作用是让resource文件可访问,而且版本号我们根据$符号来确定
<build>
<finalName>SpringCloud</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<delimiters>
<delimit>$</delimit>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
- 第二步,由于第一步已经设置了resource文件夹可访问了,所以我们在resource文件夹下的yml文件里添加info信息,现在在provider的yml增加如下内容
info:
app.name: provider-8001
company.name: www.vae.com
build.artifactId: $project.artifactId$
build.version: $project.version$
有了这两步之后,你可以点击那个服务的status试试,结果应该是如下图所示的
Eureka的自我保护机制
这个服务中心,你等一会再打开,你会发现会出来一行红字,这并不是报错,这个就是因为Eureka的自我保护机制。
下面一起来做个例子,来看看自我保护机制,我们在provider项目的yml里面改一下status的名称,加个Vae,如下:
instance-id: provider-8001Vae
热部署更新,可以不用重启,刷新浏览器,看看
status也变成Vae了,我们现在再把Vae删了,恢复原来的
instance-id: provider-8001
再热更新一下,刷新浏览器,你会发现,provider-8001Vae和provider-8001都有,都存在。
我的不知道为什么没有出来两个,我修改之后还是恢复为8001了 |
---|
这就是Eureka的自我保护机制:
服务不会立即删除,Eureka会认为是网络延迟或者堵塞,反正就是不会立马删除服务,默认90秒之后如果还是没有心跳也就是回应,那才注销。默认自我保护机制是开启的,90s时间。
Eureka的发现
服务的注册很容易理解,服务的发现我不懂,据说是给消费者看看这个服务的作用用处的
首先,把provider提供者的Controller加一个方法
@Autowired
private DiscoveryClient client;
@GetMapping(value = "/dept/discovery")
public Object discovery()
{
List<String> list = client.getServices();
System.out.println("**********" + list);
List<ServiceInstance> srvList = client.getInstances("PROVIDER-DEPT");
for (ServiceInstance element : srvList) {
System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"
+ element.getUri());
}
return this.client;
}
然后主方法加个服务发现的注解@EnableDiscoveryClient
现在启动Eureka7001服务中心,再启动provider8001项目,输入http://localhost:8001/dept/discovery
消费者项目的Controller加个代码
// 测试@EnableDiscoveryClient,消费端可以调用服务发现
@RequestMapping(value = "/consumer/dept/discovery")
public Object discovery()
{
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/discovery", Object.class);
}
然后启动项目,输入http://localhost/consumer/dept/discovery
Eureka集群
什么是集群?
所谓的集群,就是在不同的服务器上部署相同的服务。举个例子,淘宝,这么大的应用,不可能只有一个服务器,一个淘宝背后可能有上百台服务器支撑。
同样的,我们的Eureka,也不能只有一台服务器,万一这台服务器挂了怎么办?
新建Eureka集群
新建两个Eureka服务中心,一个是Eureka7002,一个是Eureka7003,新建和上面一样就不讲了,新建完成如下图
还记得我们Eureka服务中心的yml里面写的是localhost吧,现在有三个服务中心了,都写localhost就不合适了,但是我又没有多台电脑供我测试,只能修改host文件滥竽充数了。打开C:\Windows\System32\drivers\etc,找到host文件,添加下面三行
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com
现在,开始修改我们的三个服务中心的yml吧
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #因为我修改了host文件,所以这里相当于还是localhost
# hostname: localhost #eureka服务端的实例名称
client:
register-with-eureka: false #false\u8868\u793A\u4E0D\u5411\u6CE8\u518C\u4E2D\u5FC3\u6CE8\u518C\u81EA\u5DF1\u3002
fetch-registry: false #false\u8868\u793A\u81EA\u5DF1\u7AEF\u5C31\u662F\u6CE8\u518C\u4E2D\u5FC3\uFF0C\u6211\u7684\u804C\u8D23\u5C31\u662F\u7EF4\u62A4\u670D\u52A1\u5B9E\u4F8B\uFF0C\u5E76\u4E0D\u9700\u8981\u53BB\u68C0\u7D22\u670D\u52A1
service-url:
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #\u8BBE\u
defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #因为我的Eureka建立了集群,所以这里写上其他集群的地址
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称,我在host文件里面修改了
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
server:
port: 7003
eureka:
instance:
hostname: eureka7003.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
三个服务中心的yml完成了,别忘了7001里面的Maven的pom文件,复制到7002和7003里面去,其实就一个eureka-server这个需要引用而已。
现在修改一下provider的yml
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml #mybatis配置文件所在路径
type-aliases-package: com.vae.springcloud.entity #所有Entity别名类所在包
mapper-locations: classpath:mybatis/mapper/**/*.xml #mapper映射文件
spring:
application:
name: provider-dept
datasource:
# type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/shuyunquan?serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123
dbcp2:
min-idle: 5 # 数据库连接池的最小维持连接数
initial-size: 5 # 初始化连接数
max-total: 5 # 最大连接数
max-wait-millis: 200 # 等待连接获取的最大超时时间
eureka:
client: #客户端注册进eureka服务列表内
service-url:
# defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
instance:
instance-id: provider-8001 #这个是修改Eureka界面的Status名称
prefer-ip-address: true #这个是设置鼠标放在status上的时候,出现的提示,设置ip地址显示
info:
app.name: provider-8001
company.name: www.vae.com
build.artifactId: $project.artifactId$
build.version: $project.version$
就改了一个defaultZone,改成集群了。
我有一点还不明白,集群,服务中心的yml的defaultZone写的其他集群的地址,这要是有100个集群,我写100个?而且provider注册者的defaultZone也是写的所有集群的地址,也写100个?这里肯定有更好的方法,我还不知 |
启动eureka集群,也就是启动三个eureka项目,如图: