文章目录
- Eureka注册中心
- 一、服务注册与发现
- 1.1 依赖导入
- ①父工程 SpringCloud 版本管理
- ②Eureka 服务端依赖
- ③Eureka 客户端依赖
- 1.2 服务注册
- ①创建 Eureka 服务端的主类
- ②设置 Eureka 服务端的配置文件
- ③设置 Eureka 客户端的配置文件
- ④关闭自我保护机制
- 1.3 服务发现
- ①远程调用
- ②负载均衡
- 二、注册中心高可用: 搭建 Eureka 集群
- ①服务端创建两个配置文件
- ②修改本地 hosts
- ③开启两个 EurekaServer 实例
- ④修改Eureka客户端的配置文件
提示:以下是本篇文章正文内容,SpringCloud 系列学习将会持续更新
Eureka注册中心
官方文档:https://docs.spring.io/spring-cloud-netflix/docs/current/reference/html/
前面我们了解了如何对单体应用进行拆分,并且也学习了如何进行服务之间的相互调用,但是存在一个问题,就是虽然服务拆分完成,但是没有一个比较合理的管理机制,如果单纯只是这样编写,在部署和维护起来,肯定是很麻烦的。
可以想象一下,如果某一天这些微服务的端口或是地址大规模地发生改变,我们就不得不将服务之间的调用路径大规模的同步进行修改,这是多么可怕的事情。我们需要削弱这种服务之间的强关联性,因此我们需要一个集中管理微服务的平台,这时就要借助我们这一部分的主角了。
Eureka 能够自动注册并发现微服务,然后对服务的状态、信息进行集中管理,这样当我们需要获取其他服务的信息时,我们只需要向 Eureka 进行查询就可以了。
像这样的话,服务之间的强关联性就会被进一步削弱。
一、服务注册与发现
1.1 依赖导入
①父工程 SpringCloud 版本管理
我们先在父工程中添加一下 SpringCloud 的依赖 进行版本管理,这里选用 2021.0.1 版本。
官网查看:https://spring.io/projects/spring-cloud#learn
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
②Eureka 服务端依赖
现在我们就来搭建一个 Eureka 服务器,只需要创建一个新的 Maven 项目即可(eureka-server
)
接着我们为Eureka服务端添加 Eureka 依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
③Eureka 客户端依赖
我们的三个微服务客户端,首先还是需要导入 Eureka 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
回到目录…
1.2 服务注册
①创建 Eureka 服务端的主类
需要使用@EnableEurekaServer
注解:
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
②设置 Eureka 服务端的配置文件
server:
port: 8888
eureka:
instance:
hostname: localhost # eureka服务端的实例名称
client:
# 是否在服务中心注册自己, 默认为 true
register-with-eureka: false
# false表示自己就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
# 设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
好了,现在差不多可以启动了,启动完成后,直接localhost:8888
即可访问 Eureka 的管理后台:
③设置 Eureka 客户端的配置文件
spring:
application:
name: userservice
eureka:
client:
service-url:
defaultZone: http://localhost:8888/eureka
OK,无需在启动类添加注解,直接启动就可以了,然后打开 Eureka 的服务管理页面,可以看到我们刚刚开启的服务:
当我们的服务启动之后,会每隔一段时间跟 Eureka 发送一次心跳包,这样 Eureka 就能够感知到我们的服务是否处于正常运行状态。
④关闭自我保护机制
Eureka 的自我保护机制指的是,当网络发生问题导致服务访问失败时,eureka 注册中心不会马上把应用剔除,继续保留一段时间。但这样对我们实际开发来说,需要频繁重启应用的时候,不方便测试,需要将自我保护机制关闭。
Ⅰ 修改 eureka 服务端:
eureka:
server:
# 关闭自我保护机制,保证不可用服务被及时剔除
enable-self-preservation: false
# 心跳检测时间,设置成2秒
eviction-interval-timer-in-ms: 2000
Ⅱ 修改 eureka 客户端:
eureka:
instance:
# eureka客户端向服务端发送心跳的时间间隔,单位是秒(默认30秒)
lease-renewal-interval-in-seconds: 1
# eureka服务端在收到最后一次心跳后等待时间的上限,单位为秒(默认90秒),超时将会剔除服务
lease-expiration-duration-in-seconds: 2
配置完成之后,经测试可体验到在服务关闭后非常快速地剔除应用。
回到目录…
1.3 服务发现
①远程调用
那么,现在我们怎么实现服务发现呢?
原本的微服务远程调用,那么就必须要知道其他服务的地址:
RestTemplate template = new RestTemplate();
User user = template.getForObject("http://localhost:8082/user/"+uid, User.class);
修改后的微服务远程调用:
a. 我们手动将 RestTemplate 声明为一个 Bean 注册到 Ioc 容器中,然后添加@LoadBalanced
注解,这样 Eureka 就会对服务的调用进行自动发现,并提供负载均衡:
@Configuration
public class BeanConfiguration {
@Bean
@LoadBalanced // 负载均衡
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
b. 而现在有了 Eureka 之后,我们只需要用服务名称
对其查询:
@Service
public class BorrowServiceImpl implements BorrowService {
@Resource
private BorrowMapper borrowMapper;
@Resource
// RestTemplate 支持多种方式的远程调用
private RestTemplate template;
@Override
public UserBorrowView getBorrowViewByUid(int uid) {
// 现在拿到借阅关联信息了,怎么调用其他服务获取信息呢?
List<Borrow> borrowList = borrowMapper.getBorrowsByUid(uid);
// 这里不用再写IP,直接写服务名称 userservice
User user = this.template.getForObject("http://userservice/user/"+uid, User.class);
// 这里通过调用 getForObject 来请求其他服务,并将结果自动进行封装
List<Book> bookList = borrowList
.stream()
.map(b -> template.getForObject("http://bookservice/book/"+b.getBid(), Book.class))
.collect(Collectors.toList());
return new UserBorrowView(user, bookList);
}
}
现在我们就可以正常调用了:
回到目录…
②负载均衡
🐳同一个服务器多开实例,设置不同的端口:
a. Edit Configuration… -> 选中 UserApplication -> 新建目录 Move into new folder -> 在该目录下新建 Spring Boot -> 进行如下配置
b. 启动所有实例:
c. 此时,我们在 Eureka 后台也可以看到新增的实例:
🐳如何观察 Eureka 对我们多实例的负载均衡:
a. 我们有2个 UserApplication 的实例,可以在控制层的某个服务调用代码中添加日志打印:当前实例的IP:PORT
@RestController
@Slf4j
public class UserController {
@Resource
private UserService userService;
@Resource
Environment environment; // org.springframework.core.env.Environment
@GetMapping("/user/{uid}")
public User findUserById(@PathVariable("uid") int uid) throws UnknownHostException {
String hostIp = InetAddress.getLocalHost().getHostAddress();
String port = environment.getProperty("server.port");
log.info(hostIp + ":" + port + " 的findUserById()被访问了!");
return userService.getUserById(uid);
}
}
b. 然后重新启动。我们多次访问http://localhost:8082/borrow/3
,其中 BorrowService 就会进行远程调用 UserService,这时我们通过查看 UserApplication-1 和 UserApplication-2 的控制台日志,就可以发现它们是被轮循调用的。
这样,服务自动发现以及简单的负载均衡就实现完成了,并且,如果某个微服务挂掉了,只要存在其他同样的微服务实例在运行,那么就不会导致整个微服务不可用,极大地保证了安全性。
回到目录…
二、注册中心高可用: 搭建 Eureka 集群
各位可否想过这样的一个问题?虽然Eureka能够实现服务注册和发现,但是如果Eureka服务器崩溃了,岂不是所有需要用到服务发现的微服务就GG了?
为了避免,这种问题,我们也可以像上面那样,搭建Eureka集群,存在多个Eureka服务器,这样就算挂掉其中一个,其他的也还在正常运行,就不会使得服务注册与发现不可用。当然,要是物理黑客直接炸了整个机房,那还是算了吧。
我们来看看如何搭建Eureka集群,这里由于机器配置不高,就搭建两个Eureka服务器组成集群。
①服务端创建两个配置文件
application-1.yml
server:
port: 8801
spring:
application:
name: eurekaserver # 所有eureak的这个值要设置为同一个
eureka:
instance:
# 由于不支持多个localhost的Eureka服务器,但是又只有本地测试环境,所以就只能自定义主机名称了
# 如果报错主机名称改为 eureka01
hostname: eureka01
client:
# false表示自己就是注册中心
fetch-registry: false
service-url:
# 注意这里填写其他 Eureka 服务器的地址,不用写自己的
defaultZone: http://eureka02:8802/eureka
application-2.yml
server:
port: 8802
spring:
application:
name: eurekaserver
eureka:
instance:
hostname: eureka02
client:
fetch-registry: false
service-url:
defaultZone: http://eureka01:8801/eureka
②修改本地 hosts
这里由于我们修改成自定义的地址,需要在 hosts 文件中将其解析到 127.0.0.1 才能回到 localhost。
Linux 下文件路径为 /etc/hosts
Windows 下文件路径为 C:\Windows\system32\drivers\etc\hosts
,需要获取权限比较麻烦,可以利用火绒安全软件直接修改
Windows系统修改hosts后需要刷新DNS缓存使之生效,在cmd命令行中执行命令:ipconfig/flushdns
回到目录…
③开启两个 EurekaServer 实例
对创建的两个配置文件分别添加启动配置,直接使用-Dspring.profiles.active
指定启用的配置文件即可:
接着启动这两个注册中心,这两个 Eureka 管理页面都可以被访问,我们访问其中一个:
可以看到下方replicas中已经包含了另一个Eureka服务器的地址,并且是可用状态。
回到目录…
④修改Eureka客户端的配置文件
eureka:
client:
service-url:
# 将两个Eureka的地址都加入,这样就算有一个Eureka挂掉,也能完成注册
defaultZone: http://localhost:8801/eureka, http://localhost:8802/eureka
可以看到,服务全部成功注册,并且两个 Eureka 服务端都显示为已注册:
接着我们模拟一下,将其中一个Eureka服务器关闭掉,可以看到它会直接变成不可用状态:
当然,如果这个时候我们重启刚刚关闭的Eureka服务器,会自动同步其他Eureka服务器的数据。
回到目录…
总结:
提示:这里对文章进行总结:
本文是对SpringCloud的学习,学习了它的组件Eureka注册中心,包括服务的注册与发现,高可用(Eureka集群的搭建)。之后的学习内容将持续更新!!!