2021年4月7日星期三

[SpringCloud教程]3. Eureka服务注册中心集成

新微服务项目多半采用Nacos作为服务注册与发现中心,但是旧项目可能使用Eureka、zookeeper、Consul、Nacos作为服务注册中心。
新项目建议使用Nacos作为服务注册中心

  • SpringCloud教程合集: https://www.cnblogs.com/spzmmd/tag/微服务教程/
  • 案例项目地址: https://gitee.com/spzmmd/spring-cloud-demo

根项目建立

  • 建立一个maven项目,删除src目录,然后编辑pom.其中核心部分就是SpringCloud、SpringBoot、SpringCloudAlibaba的版本号
    • Spring Cloud Version: Spring Cloud Hoxton.SR8
    • Spring Cloud Alibaba Version: 2.2.5.RELEASE
    • Spring Boot Version: 2.3.2.RELEASE
<?

项目结构

  • eureka-server: Eureka服务端
  • ms-consumer: 服务消费者
  • ms-provider: 服务提供者
  • api-common: 公共模块
    f3f1de3d73b56dceb4105d400186c60a4e0033704f417bd713e0e935840ea480.png

Eureka 服务注册中心 服务端(eureka-server)

首先需要在根pom.

<modules> <module>api-common</module> <!--  <module>ms-provider</module> <module>ms-consumer</module> --> <module>eureka-server</module></modules>

单节点 Eureka Server 节点搭建

  • 在根项目下建立eureka-server目录,然后在eureka-server目录下建立pom.
<?
  • 建立src/main/java和src/main/resources目录
  • 在src/main/java目录下建立包com.spz.demo.scloud.register.eureka

5f716b2f5c0416ade2833ba23ed253620699bdad6629def64d8f52fc9f428dbf.png

  • 在eureka包下建立启动类 RegisterServerEureka.java
package com.spz.demo.scloud.register.eureka;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication@EnableEurekaServerpublic class RegisterServerEureka { public static void main(String[] args) {  SpringApplication.run(RegisterServerEureka.class, args); }}
  • 在src/main/resources目录下建立application.properties文件
    • eureka.client.service-url.defaultZone: 这里只需要配置除自己以外的其他服务端节点,因为是将本节点注册给其他注册中心,来实现互相注册的高可用集群
server.port=6001spring.application.name=@project.artifactId@# Eureka 配置# Eureka Server 实例 hostnameeureka.instance.hostname=eureka6001# 服务端不需要注册自己eureka.client.register-with-eureka=false# 服务端不需要检索服务eureka.client.fetch-registry=false# Eureka Server 向其他服务端注册自己,实现Eureka的高可用集群eureka.client.service-url.defaultZone=http://eureka6002:6002/eureka 关闭自我保护机制,保证不可用服务被及时踢除,建议生产环境保持默认#eureka.server.enable-self-preservation=false#eureka.server.eviction-interval-timer-in-ms=2000

高可用 Eureka Server 集群实现

eureka 服务端实例实现高可用集群的方法是多个Eureka Server节点互相注册。比如A、B、C三个节点,A把自己作为Eureka客户端注册到B、C节点;B把自己注册到A、C节点;C把自己注册到A、B节点。这样三个节点互相具备其他服务端节点的信息,客户端列表数据也相当于保存了三分,这时候某个服务端节点失效,并不会造成客户端信息缺失,由此实现了高可用集群。下面介绍高可用集群实现方法:

  • 配置Eureka 服务端节点所属服务器的hosts,这里采用本地部署多个Eureka服务端的方案代替
    假设三个Eureka服务端节点的hostname分别为eureka6001、eureka6002、eureka6003。(注意:不配置hosts会导致Eureka集群无法进行备份,因为必须保证每个节点的hostname不同)
127.0.0.1 eureka6001127.0.0.1 eureka6002127.0.0.1 eureka6003
  • IDEA方式启动 - eureka6001节点配置
    70b5948212d5e231ae147f03e55870bcc2729ab12d3f1b76857543c3e121e650.png
    vm options:
-Dserver.port=6001-Deureka.instance.hostname=eureka6001-Deureka.client.service-url.defaultZone=http://eureka6002:6002/eureka - eureka6002节点配置

c1c5770b3dfa3fea48b56820e6116bf38dea647650ec2b53c80486fd3ddf3376.png
vm options:

-Dserver.port=6002-Deureka.instance.hostname=eureka6002-Deureka.client.service-url.defaultZone=http://eureka6001:6001/eureka - eureka6003节点配置

5ed09e468c0b40db2d5e6d5dc03784121fd6b695203d12e7d665740f021454df.png
vm options:

-Dserver.port=6003-Deureka.instance.hostname=eureka6003-Deureka.client.service-url.defaultZone=http://eureka6002:6002/eureka src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a85d816862a34bd09054650fa911cdf2~tplv-k3u1fbpfcp-watermark.image" alt="bd6dc0716faefb1e3a12f795c362b4bc243629d2f61f6d7392e6f53dfe8e55ae.png" loading="lazy">
如图eureka6001节点的DS Replicas出现了另外两个相邻节点,说明这三个节点组成了一个集群,这时候访问另外两个节点的管理页,也能同样看到DS Replicas里出现其他两个节点。另外,当有客户端注册进服务端时,三个服务端节点里应该有同一份的客户端列表信息。至此Eureka集群搭建成功。

服务提供者集群(ms-provider)

首先需要在根pom.

<modules> <module>api-common</module> <module>ms-provider</module> <!-- <module>ms-consumer</module> --> <module>eureka-server</module></modules>

单节点ms-provider搭建

  • 在根项目下建立ms-provider目录,然后在ms-provider目录下建立pom.
<?
  • 建立src/main/java和src/main/resources目录
  • 在src/main/resources下建立application.properties文件
    • eureka.client.service-url.defaultZone: 这里配置的是Eureka服务端集群,启动后该服务将把自己注册进Eureka注册中心集群
    • spring.application.name: 将作为服务名注册进Eureka注册中心(使用RestTemplate+负载均衡来调用Eureka服务时,服务名不能有下划线)
server.port=8001spring.application.name=MS-PROVIDER# 服务追踪#spring.zipkin.base-url=http://localhost:9411#采样率值介于 0 到 1 之间,1 则表示全部采集#spring.sleuth.sampler.probability=1# eureka 配置# 是否将自己注册进 EurekaServer 默认为trueeureka.client.register-with-eureka=true# 是否从 EurekaServer 抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡eureka.client.fetchRegistry=trueeureka.client.service-url.defaultZone=http://eureka6001:6001/eureka 实例IDeureka.instance.instance-id=${spring.application.name}-${server.port}# 访问路径可以显示IP地址eureka.instance.prefer-ip-address=true# Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)eureka.instance.lease-renewal-interval-in-seconds=1# Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务eureka.instance.lease-expiration-duration-in-seconds=10
  • 在src/main/java目录下建立包com.spz.demo.scloud.provider
  • 在provider包下建立其他包、类和启动类

9bb8301caa3cdda53fc3dac668bdce10d7de139e6ce6b044eabbfa3567821cc1.png

  • IndexController.java
    package com.spz.demo.scloud.provider.controller;import com.spz.demo.scloud.common.core.bean.RestBean;import com.spz.demo.scloud.common.service.AppService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("")public class IndexController { @Autowired private AppService appService; /** * 获取项目信息 * @return */ @RequestMapping("/projectInfo") public RestBean projectInfo(){  String msg = appService.instanceNameAndPort();  return RestBean.ok(msg); }}
  • AppServiceImpl.java
    注意该该类实现的AppService.java接口存放于api-common包,该包代码请在此处查看(https://gitee.com/spzmmd/spring-cloud-demo)
    package com.spz.demo.scloud.provider.service;import com.spz.demo.scloud.common.service.AppService;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;/*** App Service 接口实现类*/@Servicepublic class AppServiceImpl implements AppService { /** * 项目端口 */ @Value("${server.port}") private Integer projectServerPort; /** * 项目名称 */ @Value("${spring.application.name}") private String projectApplicationName; @Override public String instanceNameAndPort(){  return projectApplicationName + ":" + projectServerPort; }}
  • ProviderApp.java 启动类
    package com.spz.demo.scloud.provider;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@EnableEurekaClient@EnableDiscoveryClient@SpringBootApplicationpublic class ProviderApp { public static void main(String[] args) {  SpringApplication.run(ProviderApp.class, args); }}

集群实现

客户端服务(这里是本机,所以只需要配置一次,如果是不同服务器则需要配置)也需要配置hosts,不然无法访问Eureka注册中心集群

127.0.0.1 eureka6001127.0.0.1 eureka6002127.0.0.1 eureka6003
  • IDEA方式启动 - 8001节点

bc00d06700ccf9047af2b7766374eed137c67959e950e025b9f37c1fbc88f90b.png
vm options:

-Dserver.port=8001-Deureka.client.service-url.defaultZone=http://eureka6001:6001/eureka - 8002节点

d42f34a85318f09a6896499be1d5b72389fc12c84baef9f0152d363827a6f8b5.png
vm options:

-Dserver.port=8002-Deureka.client.service-url.defaultZone=http://eureka6001:6001/eureka 这里是在application.properties里的"eureka.instance.instance-id"配置的,也即是实例ID
  • MS-PROVIDER: 这里是在application.properties里的"spring.application.name"配置的,也即是服务名(使用RestTemplate+负载均衡来调用Eureka服务时,服务名不能有下划线)
  • 69d82e13a4970b5bcf90c5e759a3eb4db24012c123d4dd6fa1adccebe3035455.png
    服务提供者集群搭建完成

    服务消费者实例(ms-consumer)

    首先需要在根pom.

    <modules> <module>api-common</module> <module>ms-provider</module> <module>ms-consumer</module> <module>eureka-server</module></modules>

    单节点ms-consumer搭建

    • 在根项目下建立ms-consumer目录,然后在ms-consumer目录下建立pom.
    <?
    • 建立src/main/java和src/main/resources目录
    • 在src/main/resources下建立application.properties文件
      • eureka.client.service-url.defaultZone: 这里配置的是Eureka服务端集群,启动后该服务将把自己注册进Eureka注册中心集群
      • spring.application.name: 将作为服务名注册进Eureka注册中心
    server.port=7001spring.application.name=MS-CONSUMER# 服务追踪#spring.zipkin.base-url=http://localhost:9411#采样率值介于 0 到 1 之间,1 则表示全部采集#spring.sleuth.sampler.probability=1# Eureka 注册中心配置# 是否将自己注册进 Eureka Server 默认为trueeureka.client.register-with-eureka=true# 实例IDeureka.instance.instance-id=${spring.application.name}-${server.port}# 访问路径可以显示IP地址eureka.instance.prefer-ip-address=true# 是否从 Eureka Server 抓取已有的注册信息,默认为true 单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡eureka.client.fetchRegistry=true# Eureka Server 集群eureka.client.service-url.defaultZone=http://eureka6001:6001/eureka src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3254c3e8104440c89771ee91a19cb80f~tplv-k3u1fbpfcp-watermark.image" alt="c31abf28bd34089a8d785084e7f29fa75a3a825df99ed03249a99338b2f38824.png" loading="lazy">

    • RestTemplateConfig.java
      • RestTemplate用于消费者远程访问服务提供者提供的接口
      • 注意需要@LoadBalanced注解,否则RestTemplate无法从服务提供者集群里获取实例
      package com.spz.demo.scloud.consumer.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;/*** RestTemplate 配置*/@Configurationpublic class RestTemplateConfig { @Bean @LoadBalanced public RestTemplate getRestTemplate(){  return new RestTemplate(); }}
    • DiscoveryEurekaController.java
      用于测试Eureka注册中心
      package com.spz.demo.scloud.consumer.controller;import com.spz.demo.scloud.common.core.bean.RestBean;import com.spz.demo.scloud.common.service.AppService;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cloud.client.ServiceInstance;import org.springframework.cloud.client.discovery.DiscoveryClient;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;import java.net.URI;import java.util.List;/*** 注册中心 - Eureka - 测试接口*/@Slf4j@RestController@RequestMapping("/discovery/eureka")public class DiscoveryEurekaController { @Autowired private DiscoveryClient discoveryClient; @Autowired private RestTemplate restTemplate; /** * 服务远程调用测试 - 使用 RestTemplate * @see AppService#instanceNameAndPort() * @return */ @RequestMapping("/appService/projectInfo") public RestBean appServiceProjectInfo(){  RestBean restBean = restTemplate.postForObject("http://MS-PROVIDER/projectInfo",null, RestBean.class);  return restBean; } /** * 获取已在 Eureka Server 注册的服务名称列表 * 注意不是服务名下的实例名称列表,是 Eureka的Application名称列表 * @return */ @RequestMapping("/services") public RestBean services(){  List<String> services = discoveryClient.getServices();  return RestBean.ok(services); } /** * 根据名称获取实例列表 * 1. 如多个服务注册到Eureka服务端,他们的名称均为MS-PROVIDER,则使用MS-PROVIDER可查询出所有已注册实例 * 2. 获取到ServiceInstance对象里包含实例的ServiceId、host、port、uri等 * @param name eg. MS-PROVIDER * @return */ @GetMapping("/instances/{name}") public RestBean instancesByName(@PathVariable(name = "name", required = true) String name){  List<ServiceInstance> instances = discoveryClient.getInstances(name);  return RestBean.ok(instances); }}
    • ConsumerApp.java 启动类
      package com.spz.demo.scloud.consumer;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@EnableEurekaClient@EnableDiscoveryClient@SpringBootApplicationpublic class ConsumerApp { public static void main(String[] args) {  SpringApplication.run(ConsumerApp.class, args); }}
    • IDEA方式启动 - 7001节点

    b8ad5c365ee75fb59971ffccf250ee1c47f48b068668965a8e2d5aa6e649281a.png
    vm options:

    -Dserver.port=7001-Deureka.client.service-url.defaultZone=http://eureka6001:6001/eureka >{"code": 2000,"message": "MS-PROVIDER:8001","data": null}{"code": 2000,"message": "MS-PROVIDER:8002","data": null}

    集群实现

    于服务提供者集群实现方式相似,这里不再赘述

    参考

    • 使用RestTemplate+负载均衡来调用Eureka服务时,服务名称不能有下划线!!
    • Eureka自我保护机制
      https://www.cnblogs.com/xishuai/p/spring-cloud-eureka-safe.html

    交流&联系

    • QQ群
      欢迎加入Java交流群(qq群号: 776241689 )

    • 公众号
      PS:小到Java后端技术、计算机基础知识,大到微服务、Service Mesh、大数据等,都是本人研究的方向。我将定期在公众号中分享技术干货,希望以我一己之力,抛砖引玉,帮助朋友们提升技术能力,共同进步!
      在这里插入图片描述

    • 博客

      • 掘金
      • CSDN
      • 博客园

    原创不易,转载请在开头著名文章来源和作者。如果我的文章对您有帮助,请点赞/收藏/关注鼓励支持一下吧❤❤❤❤❤❤









    原文转载:http://www.shaoqun.com/a/669733.html

    跨境电商:https://www.ikjzd.com/

    focalprice:https://www.ikjzd.com/w/1094.html

    extra:https://www.ikjzd.com/w/1736


    新微服务项目多半采用Nacos作为服务注册与发现中心,但是旧项目可能使用Eureka、zookeeper、Consul、Nacos作为服务注册中心。新项目建议使用Nacos作为服务注册中心SpringCloud教程合集:https://www.cnblogs.com/spzmmd/tag/微服务教程/案例项目地址:https://gitee.com/spzmmd/spring-cloud-demo
    易佰:https://www.ikjzd.com/w/1482
    naning9韩国官网:https://www.ikjzd.com/w/2401
    淘粉吧返利:https://www.ikjzd.com/w/1725
    喜讯!全国多地已开具不可抗力证明书!:https://www.ikjzd.com/home/115329
    紧急!亚马逊美国这一仓库关闭!未提供相关信息的这类产品可能会被移除!:https://www.ikjzd.com/home/137840
    漂亮人妻嗯…啊 那个少妇的气质使我彻底沦陷在她的双腿之间:http://lady.shaoqun.com/m/a/274540.html

    没有评论:

    发表评论