微服务中 Eureka 担当着注册中心的角色,全部服务节点都需要找它注册,这么重要的应用,肯定是不可能单点的,不然挂了怎么办。
一、如何实现多个一份代码多个实例?
大家最常用的可能就是直接跑3个实例,分配不同的端口。
在服务器还好,但是在本地,你同时用IDE 跑3个实例,那就太浪费电脑资源了。而且每次重启项目,都需要改一大堆配置文件,这样真的好?
其实 SpringBoot 是支持多个环境的,我们可以开发环境一个配置文件,生产环境另一个配置文件,这样,我们只需要在启动的时候指定好对应的环境,就可以不用把配置文件改来改去了。
应用到这个项目里,我们也可以做到一份代码,通过不同的启动命令,分别启动3个实例。
1、首先我们把配置文件复制3份,名字分别改成application-eureka1.yml、application-eureka2.yml、application-eureka3.yml
注意:这里是有格式要求的,必须是 application-环境名.yml (通常我们开发的时候会改成 dev 和 prod,dev为开发环境,prod 为生产环境,特殊情况下还有 test 测试环境)。
2、改各自配置文件的内容
#
# Eureka1
eureka:
client:
service-url:
defaultZone: http://localhost:8762/eureka/,http://localhost:8763/eureka/ #向其他两个Eureka注册
register-with-eureka: false #不显示在注册中心页面
spring:
application:
name: eureka1
server:
port: 8761
# Eureka2
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/,http://localhost:8763/eureka/ #向其他两个Eureka注册
register-with-eureka: false #不显示在注册中心页面
spring:
application:
name: eureka2
server:
port: 8762
# Eureka3
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/ #向其他两个Eureka注册
register-with-eureka: false #不显示在注册中心页面
spring:
application:
name: eureka3
server:
port: 8763
3、 pom.xml 文件里面,添加对应的配置
<!--配置环境的profile-->
<profiles>
<profile>
<id>eureka1</id>
<properties>
<environment>eureka1</environment>
</properties>
<activation>
<activeByDefault>true</activeByDefault> <!--如果没指定环境,默认为该环境-->
</activation>
</profile>
<profile>
<id>eureka2</id>
<properties>
<environment>eureka2</environment>
</properties>
</profile>
<profile>
<id>eureka3</id>
<properties>
<environment>eureka3</environment>
</properties>
</profile>
</profiles>
4、打包启动(Maven打包什么的,请你自己搞定)
这里我们就不需要用 IDE 启动了,我们直接通过脚本或者命令行启动就行了,这样比较不占内存,而且还可以后台启动
打开你们的终端(我这里用的是 powerShell,win10 的同学建议使用 )
cd E:\DemoProdect\SpringCloud\eureka #进入到项目目录
java -jar .\target\eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=eureka1 #通过java命令启动程序
我们直接用 --spring.profiles.active 来指定我们所使用的环境(也就是配置文件)。
这样启动还是太麻烦了,我们可以把它写成脚本
新建一个文本,写入这两行命令,然后另存为.ps1 文件,我们就可以直接在win10下启动了,我们只要把
eureka1 改成 eureka2 和 eureka3 就得到3个启动脚本,linux 和 mac 的同学可以另存为 .sh 文件(注意路径)。
双击打开就启动项目
三个不同的端口,说明环境配置成功了,我们打开页面看看
三个 Eureka 都分别向另外两个注册,再也不怕某个 Eureka实例挂掉了,我们还可以写个定时脚本定时检测他们的状态并报警,这样就更稳当了,有兴趣的可以自己研究一下。
二、构建 Eureka Client
构建 Eureka Client 的过程和 上一章构建 Eureka Server 大致一样,只是有两点需要注意的
1、 这里选的是 Eureka Discovery (不是Server)
2、这里的注解是@EnableDiscoveryClient
package com.show.client;
@SpringBootApplication
@EnableDiscoveryClient // 指定自己是Client端
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
大致的过程就是 新建项目 -> 选择Eureka Discovery -> 把pom文件里面的版本和 server 一致 -> 修改配置文件
application.yml -> 启动
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/
spring:
application:
name: client
这样,client 端就初始化完成了。
三、Eureka总结
1、@EnableEurekaServer 和 @EnableDiscoveryClient
2、@EnableDiscoveryServer 会让该实例变成注册中心,拥有注册功能,各个服务节点启动后,会在 Eureka Server 进行注册,这样 Eureka Server 就有了所有服务节点的信息
3、Eureka Server 会有心跳检测、健康检查、负载均衡等功能
4、Eureka 的高可用,生产上建议至少两台以上,保证注册中心的稳定运行
5、分布式系统中,服务注册中心是最重要的基础部分
四、分布式下服务注册的地位和原理
1、分布式系统中为什么需要服务发现?
传统分布式服务中,我们会使用负载均衡(nginx、apache)来把流量或者不同的请求分发到不同的实例节点B,但是假如实例节点B多起来,这样负载均衡的配置文件,将会变得未必复杂,而且还要针对不同的实例写不同的配置。 而且负载均衡是不会管实例状态的,如果实例挂了,负载均衡就只会直接返回404,找不到该路径。
这样时候,我们就可以使用注册中心,把不同的实例节点B,全部注册到注册中心里面,当其它节点需要调用B的服务时,直接找注册中心拿该节点的服务地址就好了。
这里看起来和负载均衡一样,但是两个对比使用后,你就会发现不一样了
1、当B节点的端口和路径改变的时候,负载均衡是需要改配置文件,重启。注册中心不需要。
2、负载均衡主要负责的是负载和转发,而注册中心还可以健康检查、心跳检测(最简单的体验就是,你想知道这个实例是否正常,找负载均衡是没用的。但是你可以在注册中心页面看到该实例是否已经注册,已注册说明他是能正常提供服务的)
负载均衡
注册中心
因此,分布式系统中,服务注册中心是最重要的基础部分,随时都应该处于提供服务的状态。
2、服务器发现与客户端发现
客户端发现
A需要调用B的服务,找注册中心的时候,注册中心会把B的所有节点信息交给A,A自行确定调用哪个B节点提供服务(轮询、hash等...),这个叫客户端发现。
优点:A可以知道所有B可用服务的地址,没有中间商赚差价
缺点:需要自己实现一套逻辑筛选出一个B节点来提供服务
例: Eureka
服务端发现
服务端发现A需要调用B服务,找注册中心的时候,注册中心会把B所有节点信息交给"代理","代理"再挑一个节点(轮询、hash等...)告诉A,让A调用,这个叫服务端发现。
优点:B节点对于A是不可见的,A只需要说要什么服务即可
缺点:需要经过一层代理,又需要配多一份配置
例: Nginx、Zookeeper 、Kubernetes
3、原理
微服务的特点就是"异构",也就是可以用不同的语言,不同类型的数据来提供服务,SpringCloud的服务调用方式是基于 Rest ,如果其他语言需要直接注册到 Eureka 中的话,就需要自己实现一个Eureka 客户端程序,比如目前 Node.js 实现了一套 eureka-js-client 。如果其他语言需要写一个 Eureka 客户端程序,只需要调用Eureka对应的 Rest 接口即可。
GitHub:https://github.com/MrXuan3168/springCloud/tree/springCloud-3
网友评论