ToB企服应用市场:ToB评测及商务社交产业平台

标题: SpringBoot: Eureka入门 [打印本页]

作者: 河曲智叟    时间: 2024-8-12 11:34
标题: SpringBoot: Eureka入门
1. IP列表

公司发展到肯定的规模之后,应用拆分是无可避免的。假设我们有2个服务(服务A、服务B),如果服务A要调用服务B,我们能怎么做呢?最简单的方法是让服务A配置服务B的所有节点的IP,在服务A内部做负载平衡调用服务B的不同节点。

这种方式有3个显着的题目
2. 反向署理

认识反向署理的人发现,反向署理不正是办理这个题目标办法吗?如果在服务A和服务B之间添加一个nginx,网络拓扑看起来就是如许的

我们需要将服务B的节点配置为upstream,界说nginx的server,服务A通过nginx调用服务B,我们看看下面的核心配置
  1. upstream service_b {  
  2.     # 默认轮询策略round-robin,默认权重1
  3.     server 192.168.100.11 weight=1;  
  4.     server 192.168.100.12 weight=2 max_fails=10 fail_timeout=30s ;
  5.     server 192.168.100.13 backup;                                   # 备用服务器,当其他服务器都不可用时才使用  
  6.     server 192.168.100.14 down;                                     # 标记为不可用,不参与负载均衡  
  7.     ip_hash;                                                       # 负载均衡策略,基于客户端IP选择,默认round-robin
  8. }
  9. server {  
  10.     listen 80;  
  11.     location / {
  12.         proxy_pass http://service_b;  
  13.         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
  14.     }  
  15. }
复制代码
通过这种方式基本办理1.1里提到的3个题目了,不过upstream的修改仍然是手动的,而且需要重启nginx。 nginx提供了一个模块ngx_http_dyups_module让我们可以通过HTTP调用动态的修改upstream,如果我们想要将service_b的节点改成下面2个节点,我们可以这么做:
  1. curl 127.0.0.1:8000/upstream/service_b  -d
  2. "server 192.168.100.11:8080 max_fails=3 fail_timeout=5s weight=10;
  3. server 192.168.100.12:8080 max_fails=3 fail_timeout=5s weight=10;"
复制代码
不过这个方案没有开始流行就已经没落了,最显着的题目是所有对服务B的调用都要经过中央节点(nginx),而且经过了一次转发,影响了调用性能。
3. 注册中央

大概在2010年开始国内的大中厂都开始走向服务化,但并没有一个成熟的中央件,dubbo、motan、hedwig都是这个期间产物。服务提供者在启动的时候会将自己注册到服务注册中央(zookeeper、consul等实现),服务消耗者从注册中央拿到服务提供者的IP,在客户端做负载平衡,直接连接服务提供者的IP,相较于反向署理的方案好处是服务A和服务B是直接调用,避免了一次中央转发。

现在主流的注册中央实现有许多,这里我们选几个常见的对比一下
名称
CAP
语言
算法
数据结构
场景
存储
Zookeeper
CP
Java
Zab协议
树ZNode
服务发现、锁、选主、配置
文件
Eureka
AP
Java
Gossip
key-value
服务发现
内存
Nacos
CP + AP
Java
Raft
key-value
服务发现、锁、选主、配置
配置推送、流量管理(灰度发布)
MySQL
Consul
AP
Go
Raft
key-value
雷同于Nacos
文件
一样平常Java语言开发的新体系的注册中央是在Eureka和Nacos之间选择,Eureka自然和Spring Cloud集成,适用简单,固然功能也相当较弱。我们先来看看Eureka的使用。
4. Eureka入门

1. 创建应用

先创建Spring Boot应用,参见1. 手动创建应用,引入Spring Cloud的依赖管理
  1. <project>
  2.     ...
  3.     <parent>
  4.         <groupId>org.springframework.boot</groupId>
  5.         <artifactId>spring-boot-starter-parent</artifactId>   <!-- 创建为SpringBoot应用 -->
  6.         <version>3.2.7</version>
  7.     </parent>
  8.     ...
  9.     <properties>
  10.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  11.     </properties>
  12.     <dependencyManagement>
  13.         <dependencies>
  14.             <dependency>
  15.                 <groupId>org.springframework.cloud</groupId>
  16.                 <artifactId>spring-cloud-starter-parent</artifactId>  <!-- 使用Spring Cloud依赖 -->
  17.                 <version>2023.0.0</version>
  18.                 <type>pom</type>
  19.                 <scope>import</scope>
  20.             </dependency>
  21.         </dependencies>
  22.     </dependencyManagement>
  23.     <dependencies>
  24.         <dependency>
  25.             <groupId>org.springframework.boot</groupId>
  26.             <artifactId>spring-boot-starter-web</artifactId>
  27.         </dependency>
  28.         <dependency>
  29.             <groupId>org.springframework.cloud</groupId>
  30.             <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> <!-- 添加EurekaServer依赖 -->
  31.         </dependency>
  32.     </dependencies>
  33. </project>
复制代码
2. 启动类

添加启动类,除了正常的Spring Boot应用的注解,额外增加了@EnableEurekaServer注解
  1. package org.keyniu;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
  5. @SpringBootApplication
  6. @EnableEurekaServer
  7. public class StartEurekaServer {
  8.     public static void main(String[] args) {
  9.         SpringApplication.run(StartEurekaServer.class, args);
  10.     }
  11. }
复制代码
3. 核心配置

创建配置文件 application.yml,包含的内容如下,我们我看看每个配置字段的含义
配置
含义
Eureka字段
spring.application.name
应用名,注册Eureka是的应用名
application.instance.app
eureka.instance.hostname
运行实例的主机名或IP,默认取当前呆板的主机名 ;
为了方便辨认一样平常会在/etc/hosts绑定IP和主机名,设置对应节点呆板名 ;
Docker环境会选择prefer-ip-address=true,直接接纳IP地点
application.instance.hostName
eureka.instance.lease-renewal-interval-in-seconds
客户端向EurekaServer续租的心跳,默认30s
application.instance.leaseInfo.renewalIntervalInSecs
eureka.instance.lease-expiration-duration-in-seconds
最大的心跳时间隔断,高出时间没心跳的客户端被认为宕机,默认90s
application.instance.leaseInfo.durationInSecs
eureka.server.eviction-interval-timer-in-ms
Eureka定时任务,清理lease-expiration-duration没心跳的节点,默认60s

eureka.client.register-with-eureka
是否向EurekaServer注册自己

eureka.client.fetch-registry
是否从EurekaServer获取注册表信息

eureka.client.registry-fetch-interval-seconds
从EurekaServer获取注册表信息的时间隔断

eureka.client.serviceUrl.defaultZone
客户端向这个地点注册和拉取注册信息,服务端节点用它来感知其他peer节点

eureka.server.wait-time-in-ms-when-sync-empty
长轮询的概念,同步数据时如果没有数据变动,请求会阻塞等候的时间

eureka.server.renewal-percent-threshold
心跳到底比例,如果少于少于这个比例,不会清理无心跳的节点,默认0.85

留意点:
  1. server:
  2.   port: 8080
  3. spring:
  4.   application:
  5.     name: keyniu-eureka-server
  6. eureka:
  7.   instance:
  8.     hostname: localhost
  9.     lease-renewal-interval-in-seconds: 30
  10.     lease-expiration-duration-in-seconds: 90
  11.   client:
  12.     register-with-eureka: false
  13.     fetch-registry: false
  14.     service-url:
  15.       defaultZone: http://127.0.0.1:${server.port}/eureka/
  16.   server:
  17.     wait-time-in-ms-when-sync-empty: 5
  18.     enable-self-preservation: true
  19.     eviction-interval-timer-in-ms: 10000
  20.     renewal-percent-threshold: 0.85
复制代码
5. REST API

默认Eureka的接口返回的XML,可以通过提交请求时指定Accept HTTP头设置相应内容的格式为JSON,这一点对所有接口有用,后续不再赘述
  1. curl -s -H 'Accept: application/json' http://192.168.31.52:8080/eureka/apps/${app}/${instanceId}
复制代码
1. 获取所有实例

通过curl http://192.168.31.52:8080/eureka/apps能检察所有可用的节点列表,包罗所有的应用(application),应用下所有的节点(instance),节点的元数据(metadata)、租约(leaseInfo)等等

2. 指定app的实例

通过如下下令读取数据,这里的KEYNIU-EUREKA-SERVER是app,需要更换成对应的值。
  1. curl http://192.168.31.52:8080/eureka/apps/${app}
  2. curl http://192.168.31.52:8080/eureka/apps/KEYNIU-EUREKA-SERVER
复制代码
3. 指定app/instanceId的实例

通过如下下令读取数据,其中KEYNIU-EUREKA-SERVER是app,Randy:keyniu-eureka-server:8080是instanceId
  1. curl http://192.168.31.52:8080/eureka/apps/${app}/${instanceId}
  2. curl http://192.168.31.52:8080/eureka/apps/KEYNIU-EUREKA-SERVER/Randy:keyniu-eureka-server:8080
复制代码
4. 服务上下线

通过修改instance的status字段,我们能控制服务的上下线,比如将节点状态改为OUT_OF_SERVICE
  1. curl -v -XPUT http://192.168.31.52:8080/eureka/apps/${app}/${instanceId}/status?value=OUT_OF_SERVICE
  2. curl -v -XPUT http://192.168.31.52:8080/eureka/apps/KEYNIU-EUREKA-SERVER/Randy:keyniu-eureka-server:8080/status?value=OUT_OF_SERVICE
复制代码
如果想让节点恢复为上线状态,通过如下下令修改
  1. curl -v -XDELETE http://192.168.31.52:8080/eureka/apps/${app}/${instanceId}/status?value=UP
  2. curl -v -XDELETE http://192.168.31.52:8080/eureka/apps/KEYNIU-EUREKA-SERVER/Randy:keyniu-eureka-server:8080/status?value=UP
复制代码
5. 更新元数据

比如我们要在元数据里添加一个admin字段,值是zhangsan,我们可以这么做
  1. curl -v -XPUT http://192.168.31.52:8080/eureka/apps/${app}/${instanceId}/metadata?${key}=${value}
  2. curl -v -XPUT http://192.168.31.52:8080/eureka/apps/KEYNIU-EUREKA-SERVER/Randy:keyniu-eureka-server:8080/metadata?admin=zhangsan
复制代码

6. 新增instance

通过POST请求,请求体可以是JSON,格式按我们读取到的实例格式,假设我们要新增一个节点: Randy1:keyniu-eureka-server:8080, 下令看起来是如许的
  1. curl -v -H 'Content-Type: application/json' -XPOST http://192.168.31.52:8080/eureka/apps/KEYNIU-EUREKA-SERVER -d '{
  2.   "instance": {
  3.     "instanceId": "Randy1:keyniu-eureka-server:8080",
  4.     "hostName": "192.168.31.53",
  5.     "app": "KEYNIU-EUREKA-SERVER",
  6.     "ipAddr": "192.168.31.53",
  7.     "status": "UP",
  8.     "overriddenStatus": "UNKNOWN",
  9.     "port": {
  10.       "$": 8080,
  11.       "@enabled": "true"
  12.     },
  13.     "securePort": {
  14.       "$": 443,
  15.       "@enabled": "false"
  16.     },
  17.     "countryId": 1,
  18.     "dataCenterInfo": {
  19.       "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
  20.       "name": "MyOwn"
  21.     },
  22.     "leaseInfo": {
  23.       "renewalIntervalInSecs": 30,
  24.       "durationInSecs": 90,
  25.       "registrationTimestamp": 1719660811233,
  26.       "lastRenewalTimestamp": 1719661187133,
  27.       "evictionTimestamp": 0,
  28.       "serviceUpTimestamp": 1719655154360
  29.     },
  30.     "metadata": {
  31.       "admin": "zhangsan",
  32.       "management.port": "8080",
  33.       "group": "secondKill"
  34.     },
  35.     "homePageUrl": "http://192.168.31.53:8080/",
  36.     "statusPageUrl": "http://192.168.31.53:8080/actuator/info",
  37.     "healthCheckUrl": "http://192.168.31.53:8080/actuator/health",
  38.     "vipAddress": "keyniu-eureka-server",
  39.     "secureVipAddress": "keyniu-eureka-server",
  40.     "isCoordinatingDiscoveryServer": "true",
  41.     "lastUpdatedTimestamp": "1719660811233",
  42.     "lastDirtyTimestamp": "1719655154170",
  43.     "actionType": "ADDED"
  44.   }
  45. }'
复制代码
7. 删除instance

通过指定app、instanceId删除对应实例
  1. curl -XDELETE http://192.168.31.52:8080/eureka/${app}/${instanceId}
  2. curl -XDELETE http://192.168.31.52:8080/eureka/KEYNIU-EUREKA-SERVER/Randy1:keyniu-eureka-server:8080
复制代码
8. 发送心跳

  1. curl -XPUT http://192.168.31.52:8080/eureka/apps/${app}/${instanceId}
  2. curl -XPUT http://192.168.31.52:8080/eureka/apps/KEYNIU-EUREKA-SERVER/Randy1:keyniu-eureka-server:8080
复制代码
6. 案例解析

现在我们反过来,从Eureka UI来看,显示的每个字段是从何而来,怎么配置
1. Eureka首页

下图是Eureka UI首页显示的内容,我们主要关系其中的6个显示字段,对应图上的数字,下面列表中是它的分析


2. 注册表信息

通过Eureka Server的REST接口,我们能读到注册表信息,下面这个连接能检察所有的APP信息,不过我们这里只有一个节点
http://127.0.0.1:8080/eureka/apps
下面是其中一个节点的内容,下面有序列表的数字对应图片里的数字



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4