前言
现在的项目很多都是前后端分离的,在前后端分离架构中,服务层被拆分成了很多的微服务,微服务的信息如何管理?Spring Cloud中提供服务注册中心来管理微服务信息。
使用服务注册中心的理由:
- 微服务数量众多,要进行远程调用就需要知道服务端的ip地址和端口,注册中心帮助我们管理这些服务的ip和端口。
- 微服务会实时上报自己的状态,注册中心统一管理这些微服务的状态,将存在问题的服务踢出服务列表,客户端获取到可用的服务进行调用。
1、Eureka介绍
Spring Cloud Eureka 是对Netflix公司的Eureka的二次封装,它实现了服务治理的功能,Spring Cloud Eureka提供服务端与客户端,服务端即是Eureka服务注册中心,客户端完成微服务向Eureka服务的注册与发现。服务端和客户端均采用Java语言编写。客户端和服务端的关系如下图:
说明如下:
- Eureka Server是服务端,负责管理各微服务结点的信息和状态。
- 在微服务上部署Eureka Client程序,远程访问Eureka Server将自己注册在Eureka Server。
- 微服务需要调用另一个微服务时从Eureka Server中获取服务调用地址,进行远程调用。
2、Eureka Server服务端搭建
所有注册了的微服务都会在这里管理。下面介绍单机版和高可用环境下Eureka Server的搭建。
(1)单机版搭建
a、 pom依赖
<dependencies>
<!-- eureka服务端依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.2.2.RELEASE</version>
<!-- 需要排除自身的gson包,要不然启动报错 -->
<exclusions>
<exclusion>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
这里需要注意一下,gson的包冲突了,需要排除一个,否则项目启动不起来。
b、yml配置
server:
port: 20000
spring:
application:
name: eureka-server
## eureka配置
eureka:
## 客户端
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://localhost:20000/eureka/
## 服务端
server:
enable-self-preservation: false
eviction‐interval‐timer‐in‐ms: 600000
## 实例地址
instance:
hostname: 127.0.0.1
参数说明:
- registerWithEureka:服务注册,是否注册到Eureka服务中,单机版不用,被其它服务调用时需向Eureka注册。
- fetchRegistry:服务发现,是否从Eureka服务中获取注册信息,单机版不用,需要从Eureka中查找要调用的目标服务时需要设置为true。
- service-url.defaultZone:配置上报Eureka服务地址高可用状态配置对方的地址,单机状态配置自己。
- enable-self-preservation:自保护设置,开发环境下设为false。
- eviction-interval-timer-in-ms:清理失效结点的间隔,默认单位为ms,在这个时间段内如果没有收到该结点的上报则将结点从服务列表中剔除。
c、启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class,args);
}
}
@EnableEurekaServer注解表示这是一个Eureka的服务端。
d、测试
下面启动服务进行测试:
红字部分翻译为:自我保护模式被关闭。在网络或其他问题的情况下可能不会保护实例失效。
因为Eureka Server有一种自我保护模式,当微服务不再向Eureka Server上报状态,Eureka Server会从服务列表将此服务删除,如果出现网络异常情况(微服务正常),此时Eureka server进入自保护模式,不再将微服务从服务列表删除。在开发阶段建议关闭自保护模式。
(2)高可用环境搭建
Eureka Server 高可用环境需要部署两个Eureka server,它们互相向对方注册。如果在本机启动两个Eureka需要注意两个Eureka Server的端口要设置不一样。
说明:
- 在实际使用时Eureka Server至少部署两台服务器,实现高可用。
- 两台Eureka Server互相注册。
- 微服务需要连接两台Eureka Server注册,当其中一台Eureka死掉也不会影响服务的注册与发现。
- 微服务会定时向Eureka server发送心跳,报告自己的状态。
- 微服务从注册中心获取服务地址以RESTful方式发起远程调用。
直接将刚才单机版的工程复制一份:
eureka-server是原工程,eureka-server2是复制的,其他内容不变,只用修改yml的配置。
eureka-server的yml配置修改如下:
server:
port: 20000
spring:
application:
name: eureka-server
## eureka配置
eureka:
## 客户端
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:20001/eureka/
## 服务端
server:
enable-self-preservation: false
eviction‐interval‐timer‐in‐ms: 600000
## 实例地址
instance:
hostname: 127.0.0.1
eureka-server2的yml配置修改如下:
server:
port: 20001
spring:
application:
name: eureka-server2
## eureka配置
eureka:
## 客户端
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:20000/eureka/
## 服务端
server:
enable-self-preservation: false
eviction‐interval‐timer‐in‐ms: 600000
## 实例地址
instance:
hostname: 127.0.0.1
注意,两个工程的端口不要一致,register-with-eureka和fetch-registry设置为true,service-url.defaultZone地址设置为对方的。
然后启动这两个工程,访问20000端口:
然后访问20001端口:
这两个服务注册中心互相向对方发送状态心跳,需要注册的微服务需要同时配置这两个服务的地址,那么其中的一个注册中心服务挂掉了,另一台可以照常提供微服务管理功能。两台都挂了就没什么办法了,只能重启了。
3、微服务注册
现在测试将另外一个微服务工程注册到服务中心,如下:
a、pom依赖
<!-- eureka客户端依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.2.RELEASE</version>
<exclusions>
<!-- 排除掉jackson-core包,否则会冲突 -->
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</exclusion>
<!-- 排除掉gson包 -->
<exclusion>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</exclusion>
</exclusions>
</dependency>
b、yml配置
在application.yml中添加如下配置:
## eureka配置
eureka:
## 客户端
client:
## 服务注册开关,需要打开
register-with-eureka: true
## 服务发现开关,需要打开
fetch-registry: true
## 向两个注册中心中注册
service-url:
defaultZone: http://localhost:20000/eureka/,http://localhost:20001/eureka/
## 实例地址
instance:
## 将自己的IP地址注册到服务注册中心
prefer-ip-address: true
ip-address: 127.0.0.1
## 指定注册后实例的ID,这里用工程名:端口号
instance-id: ${spring.application.name}:${server.port}
c、启动类
@SpringBootApplication
//包扫描
@EntityScan(basePackages = {"com.ycz.domain.person","com.ycz.domain.music"})
@ComponentScan(basePackages = {"com.ycz.api"})
@ComponentScan(basePackages = {"com.ycz.swagger"})
@EnableDiscoveryClient
public class SwaggerApplication {
public static void main(String[] args) {
SpringApplication.run(SwaggerApplication.class, args);
}
}
这里加了一个@EnableDiscoveryClient配置,该注解表示这个微服务是eureka注册中心的一个客户端。
d、测试
启动上面两个eureka注册中心服务工程,然后启动这个要注册到中心的微服务,访问20000端口:
再访问20001端口:
发现这个微服务已经注册到两个eureka服务中心了,微服务注册成功。
4、总结
spring cloud封装的eureka很好用,对于微服务注册之后的管理十分方便,我这里在引入eureka服务端依赖的时候启动报错了,原因是gson包冲突了,在引入eureka客户端依赖的时候启动也报错了,原因是gson包和jackson-core包冲突了,排除依赖往往是很烦的,尤其是用eclipse,但只要耐住性子,会找到的。