首页 > 其他分享 >Eureka注册中心

Eureka注册中心

时间:2023-06-18 20:12:47浏览次数:40  
标签:服务 中心 eureka 注册 http Eureka public

1.注册中心

服务注册中心是服务实现服务化管理的核心组件,类似于目录服务的作用。
主要用来存储服务信息,例如提供者url、路由信息等。
服务注册中心是的微服务架构中最基础的设施之一。
在微服务架构流行之前。注册中心就已经开始出现在分布式架构的系统中
Dubbo 是一个在国内比较流行的分布式框架,被大量的中小型互联网公司所采用,
它提供了比较完善的消息治理功能,而服务治理的实现主要依靠的就是注册中心。
注册中心可以说是微服务架构中的“通讯录”,它记录了服务和服务地址的映射关系。
在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就到这里找到服务的地址,进行调用。
总结:服务注册中心的作用就是服务的注册和服务的发现。

2.类别

  • Netflix Eureka
  • Alibaba Nacos
  • HashiCorp Consul
  • Apache ZooKeeper
  • CoreOS Etcd
  • CNCF CoreDNS

3.作用

在分布式系统中,我们不仅仅是需要在注册中心找到服务和服务地址的映射关系这么简单,我们还需要考虑更多更复杂的问题:

  • 服务注册后,如何被及时发现
  • 服务宕机后,如何及时下线
  • 服务如何有效的水平扩展
  • 服务发现时,如何进行路由
  • 服务异常时,如何进行降级
  • 注册中心如何实现自身的高可用
    这些问题的解决都依赖于注册中心。简单看,注册中心的功能有点类似于DNS服务器或者负载均衡器,
    而实际上,注册中心作为微服务的基础组件,可能要更加复杂,也需要更多的灵活性和时效性。
    解决问题:
  • 服务管理
  • 服务的依赖关系管理

4.Eureka概念

Eureka是Netflix开发的服务发现组件,本身是一个基于REST的服务。Spring Cloud将它集成在其子项目Spring Cloud Netfix中
实现Spring Cloud的服务注册与发现,同时还提供了负载均衡、故障转移等能力。
读作 e rui ka

5.三种角色

  • Eureka Server
    通过Register、Get、 Renew 等接口提供服务的注册和发现。
  • Application Service (Service Provider)
    服务提供方,把自身的服务实例注册到Eureka Server中。
  • Application Client (Service Consumer)
    服务调用方,通过Eureka Server获取服务列表,消费服务。

6.单节点注册中心实现

  • 父模块pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.4.RELEASE</version>
  </parent>

  <properties>
    <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  • 注册中心模块pom.xml
<!--    继承父依赖-->
    <parent>
        <artifactId>cloud1</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<!--            <version>2.2.3.RELEASE</version>-->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
  • application.yml
    Eureka默认开启将自己注册至注册中心和从注册中心获取服务注册信息的配置
    如果是单节点注册中心的话,要关闭两个配置项。否则报错
server:
  port: 8761

spring:
  application:
    name: eureka-server

eureka:
  instance:
    hostname: localhost
  client:
    #是否将自己注册到注册中心
    register-with-eureka: false
    #是否从注册中心获取服务注册信息
    fetch-registry: false
    #注册中心对外路径
    service-url:
      defaultZone: http://${spring.cloud.client.ip-address}:${server.port}/eureka/
  • 启动类
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class);

    }
}

7.多节点注册中心实现

  • 注册中心1
    application.yml
server:
  port: 8761

spring:
  application:
    name: eureka-server

eureka:
  instance:
    hostname: eureka1
  client:
    #是否将自己注册到注册中心
    register-with-eureka: false
    #是否从注册中心获取服务注册信息
    fetch-registry: false
    #注册中心对外路径
    service-url:
      defaultZone: http://localhost:8762/eureka/
  • 注册中心2
    application.yml
    对外路径引用对方的接口
server:
  port: 8762

spring:
  application:
    name: eureka-server
 
eureka:
  instance:
    hostname: eureka2
  client:
    #是否将自己注册到注册中心
    register-with-eureka: false
    #是否从注册中心获取服务注册信息
    fetch-registry: false
    #注册中心对外路径
    service-url:
      defaultZone: http://localhost:8761/eureka/

显示Ip和端口

  • application.yml加入
eureka:
  instance:
    hostname: eureka2
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${server.port}

8.发布者

  • Product
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product implements Serializable {

    private Integer id;
    private String name;
    private Integer num;
    private Double price;
}
  • ProductService
public interface ProductService {
    List<Product> listProducts();
}
  • ProductServiceImpl
@Service
public class ProductServiceImpl implements ProductService{

    @Override
    public List<Product> listProducts() {
        return Arrays.asList(
                new Product(1,"lwx",2,1000D),
                new Product(2,"xx",2,2000D)
        );
    }
}
  • ProductController
@RestController
@RequestMapping("product")
public class ProductController {

    @Autowired
    private ProductService productService;

    @GetMapping("/list")
    public List<Product> listProducts(){
        return productService.listProducts();
    }
}
  • application.yml
server:
  port: 7070

spring:
  application:
    name: provider

eureka:
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
  client:
    #注册中心对外路径
    service-url:
      defaultZone: http://localhost:8761/eureka/, http://localhost:8761/eureka/

9.消费者

  • Order
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order implements Serializable {
    private Integer id;
    private String no;
    private String address;
    private Double price;
    private List<Product> productList;
}
  • OrderService
public interface OrderService {
    Order selectOrderById(Integer id);
}
  • OrderServiceImpl三种方法实现
    先在启动类加入Bean
@SpringBootApplication
@EnableEurekaServer
public class App
{
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main( String[] args ) {

        SpringApplication.run(App.class);
    }
}

三种方法

  • 1.DiscoveryClient: 通过元数据获取服务信息
private List<Product> selectOrderByDiscoveryClient(){
        //拼接地址
        StringBuffer sb = null;

        //获取服务列表
        List<String> serviceIds = discoveryClient.getServices();
        if(CollectionUtils.isEmpty(serviceIds)){
            return null;
        }

        //根据服务名称获取服务
        List<ServiceInstance> serviceInstances = discoveryClient.getInstances("provider");
        if(CollectionUtils.isEmpty(serviceInstances)){
            return null;
        }

        ServiceInstance serviceInstance = serviceInstances.get(0);
        sb = new StringBuffer();
        sb.append("http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/product/list");

        //ResponseEntity 封装返回数据
        ResponseEntity<List<Product>> response = restTemplate.exchange(
                sb.toString(),
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<Product>>() {}
        );
        return response.getBody();
    }
  • 2.LoadBalancerClient: Ribbon的负载均衡器
private List<Product> selectOrderByLoadBalancerClient(){
        //拼接地址
        StringBuffer sb = null;

        ServiceInstance serviceInstance = loadBalancerClient.choose("provider");
        if(serviceInstance == null){
            return null;
        }
        sb = new StringBuffer();
        sb.append("http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/product/list");

        //ResponseEntity 封装返回数据
        ResponseEntity<List<Product>> response = restTemplate.exchange(
                sb.toString(),
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<Product>>() {}
        );
        return response.getBody();
    }
  • 3.@LoadBalanced:通过注解开启Ribbon的负载均衡器
    先在启动类加入注解
    @Bean
    @LoadBalanced //负载均衡注解
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
 private List<Product> selectOrderByLoadBalancerAnnoation(){
        //ResponseEntity 封装返回数据
        ResponseEntity<List<Product>> response = restTemplate.exchange(
                "http://provider/product/list",
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<Product>>() {}
        );
        return response.getBody();
    }
  • OrderController
@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @GetMapping("/{id}")
    public Order selectOrderById(@PathVariable("id") Integer id){
        return orderService.selectOrderById(id);
    }
}
  • application.yml
server:
  port: 9090

spring:
  application:
    name: consumer

#不注册
eureka:
  client:
    #是否将自己注册到注册中心
    register-with-eureka: false
    #间隔多久从服务器拉取注册信息 默认30s
    registry-fetch-interval-seconds: 10
    #注册中心对外路径
    service-url:
      defaultZone: http://localhost:8761/eureka/, http://localhost:8761/eureka/

10.原理

  • Register(服务注册): 把自己的IP和端口注册给Eureka.|
  • Renew(服务续约):发送心跳包,每30秒发送一次,告诉Eureka自己还活着。如果90秒还未发送心跳,宕机。
  • Cancel(服务下线):当Provider关闭时会向Eureka发送消息,把自己从服务列表中删除。防止Consumer调用到不存在的服
  • Get Registry(获取服务注册列表):获取其他服务列表。
  • Replicate(集群中数据同步): Eureka 集群中的数据复制与同步。
  • Make Remote Call(远程调用):完成服务的远程调用。

11.CAP原则

CAP原则又称CAP定理,指的是在一个分布式系统中具有以下其中两个特性:

  • Consistency (一致性)

  • Availability (可用性)

  • Partition tolerance (分区容错性)
    CAP 三者不可兼得。

  • Consistency:也叫做数据原子性,系统在执行某项操作后仍然处于一致的状态。
    在分布式系统中,更新操作执行成功后所有的用户都应该读到最新的值,这样的系统被认为是具有强一致性的。
    等同于所有节点访问同一份最新的数据副本。

  • Availability:每一个操作总是能够在一定的时间内返回结果,这里需要注意的是"一定时间内"和"返回结果"。
    一定时间内指的是,在可以容忍的范围内返回结果,结果可以是成功或者是失败。

  • Partition与tolerance:在网络分区的情况下,被分隔的节点仍能正常对外提供服务
    (分布式集群,数据被分布存储在不同的服务器上,无论什么情况,服务器都能正常被访问)。

11.1 取舍策略

11.1.取舍策略
CAP三个特性只能满足其中两个,那么取舍的策略就共有三种:

  • CA withoutP:如果不要求P (不允许分区),则C (强一 致性)和A (可用性)是可以保证的。但放弃P的同时也就意味着放
    弃了系统的扩展性,也就是分布式节点受限,没办法部署子节点,这是违背分布式系统设计的初衷的。
  • CP withoutA: 如果不要求A (可用),相当于每个请求都需要在服务器之间保持强一致,而P (分区)会导致同步时间无限延
    长(也就是等待数据同步完才能正常访问服务),-旦发生网络故障或者消息丢失等情况,就要牺牲用户的体验,等待所有数
    据全部一致了之后再让用户访问系统。设计成CP的系统其实不少,最典型的就是分布式数据库,如Redis、HBase等。 对于
    这些分布式数据库来说,数据的一致性是最基本的要求,因为如果连这个标准都达不到,那么直接采用关系型数据库就好,没
    必要再浪费资源来部署分布式数据库。
  • AP withoutC: 要高可用并允许分区,则需放弃一 致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只
    能用本地数据提供服务,而这样会导致全局数据的不一致性。典型的应用就如某米的抢购手机场景,可能前几秒你浏览商品的
    时候页面提示是有库存的,当你选择完商品准备下单的时候,系统提示你下单失败,商品已售完。这其实就是先在A (可用
    性)方面保证系统可以正常的服务,然后在数据的一致性方面做了些牺牲,虽然多少会影响一些用户体验,但也不至于造成用
    户购物流程的严重阻塞。

12.Eureka自我保护

一·般情况下,服务在Eureka上注册后,会每30秒发送心跳包,Eureka 通过心跳来判断服务是否健康,同时会定期删除超过90秒没有发送心跳的服务。
有两种情况会导致Eureka Server收不到微服务的心跳

  • 微服务自身的原因
  • 微服务与Eureka之间的网络故障

12.1 自我保护模式

自我保护模式
Eureka Server在运行期间会去统计心跳失败比例在15分钟之内是否低于85%,如果低于85%,Eureka Server会将这些实例保
护起来,让这些实例不会过期,同时提示一个警告。 这种算法叫做Eureka Server的自我保护模式。

12.2 为什么要启动自我保护

  • 因为同时保留“好数据"与"坏数据"总比丢掉任何数据要更好,当网络故障恢复后,这个Eureka节点会退出"自我保护模式”。
  • Eureka还有客户端缓存功能(也就是微服务的缓存功能):即使Eureka集群中所有节点都宕机失效,微服务的Provider和Consumer都能正常通信。
  • 微服务的负载均衡策略会自动剔除死亡的微服务节点。

12.3.如何关闭自我保护

eureka:
  server :
    enable-self-preservation: false # true: 开启自我保护模式,false: 关闭自我保护模式
    eviction-interval-timer-in-ms: 60000 #清理间隔(单位:毫秒,默认是60*1000)

13.Eureka优雅停服

配置了优雅停服以后,将不需要Eureka Server中配置关闭自我保护。使用actuator实现。

  • pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  • application.yml
#度量指标监控和健康检查
management:
  #开启shutdown端点访问
  endpoints:
    web:
      exposure:
        include: shutdown
  #开启shutdown实现优雅停服
  endpoint:
    shutdown:
      enabled: true

便用POST请求访问: http/:localhost:7070/actuator/shutdown

14.Eureka安全认证

  • pom.xml
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>
  • application.yml
spring:
  application:
    name: eureka-server
  #安全认证
  security:
    user:
      name: root
      password: 1234
  • 修改所有集群节点的url
defaultZone: http://root:1234@localhost:8761/eureka/

14.1 过滤CSRF

Eureka会自动化配置CSRF防御机制,Spring Security认为post, PUT, and DELETE http methods都是有风险的
如果这些method发送过程中没有带上CSRF token的话,会被直接拦截并返回403 forbidden,
多节点注册中心会无法注册

14.2 解决方法

  • 1.CSRF忽略路径
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        //忽略该路径下请求
        http.csrf().ignoringAntMatchers("/eureka/**");
    }
}
  • 2.保持密码验证的同时禁用CSRF防御机制
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
      
        http.csrf().disable().authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .httpBasic();
    }
}

标签:服务,中心,eureka,注册,http,Eureka,public
From: https://www.cnblogs.com/lwx11111/p/17489665.html

相关文章

  • OPCDA注册后 winform运行却报错
    此错误原因为未注册dll但是我已经注册了之所以会出现这个问题是因为平台不兼容将目标平台改成x86即可 ......
  • AI绘图新玩法「艺术风二维码」保姆级教程分享,注册账号就能玩,一分钟出图,定制自己的二维
    大家好,我是卷了又没卷,薛定谔的卷的AI算法工程师「陈城南」~担任某大厂的算法工程师,带来最新的前沿AI知识和工具,包括AI相关技术、ChatGPT、AI绘图等,欢迎大家交流~。最近AI绘图界又出了一个现象级的玩法,「艺术化二维码」生成,先看个网上比较火的图了解一下。上面这个图就是今天介绍的......
  • AI绘图新玩法「艺术风二维码」保姆级教程分享,注册账号就能玩,一分钟出图,定制自己的二维
    大家好,我是卷了又没卷,薛定谔的卷的AI算法工程师「陈城南」~担任某大厂的算法工程师,带来最新的前沿AI知识和工具,包括AI相关技术、ChatGPT、AI绘图等,欢迎大家交流~。最近AI绘图界又出了一个现象级的玩法,「艺术化二维码」生成,先看个网上比较火的图了解一下。上面这个图就是今天介......
  • 微服务配置中心选型比较——Nacos、Apollo
    创建配置中⼼,将配置从各个应⽤中剥离出来,对配置进⾏统⼀管理,应⽤⾃身不需要⾃⼰去管理配置.1.概述随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关、参数的配置、服务器的地址……对程序配置的期望值也越来越高:配置修改后实时生效,分环境、分集群管理配置,代码安全、审核机......
  • springboot注册过滤器
    springboot注册过滤器需要使用过滤器的话,优先选择拦截器。因为拦截器符合aop思想。在springboot中使用过滤器有三种方式。分别如下方式一:传统web在传统javaweb、ssm中使用过滤器差不多类似,这里以java配置为例,实现Filter接口@WebFilter("/*")publicclassMyFilter01i......
  • springboot @Bean自动注册
    这个注解,可以注册Bean到spring容器中@BeanpublicXXXBeanxxxBean(){returnnewXXXBean();}这个注解也可以用在void方法上,用在在spring容器启动后固定执行某个代码逻辑:@BeanpublicvoidxxxHandler(){System.out.println("我想容器启动后执行一次某个代......
  • Docker 安装 Nacos 注册中心
    废话不多说直接上安装脚本:dockerrun-d--namenacos2.0.4--restart=always\-eMODE=standalone\-eJVM_XMS=256m\-eJVM_XMX=512m\-eSPRING_DATASOURCE_PLATFORM=mysql\-eMYSQL_SERVICE_HOST=localhost\-eMYSQL_SERVICE_PORT=3307\-eMYSQL_SERVICE_DB_NAME=n......
  • Docker 安装 Nacos 注册中心
    废话不多说直接上安装脚本:dockerrun-d--namenacos2.0.4--restart=always\-eMODE=standalone\-eJVM_XMS=256m\-eJVM_XMX=512m\-eSPRING_DATASOURCE_PLATFORM=mysql\-eMYSQL_SERVICE_HOST=localhost\-eMYSQL_SERVICE_PORT=3307\-eMYSQL_SERVICE_DB_NAME=......
  • 找出星型图的中心节点
    有一个无向的星型图,由n个编号从1到n的节点组成。星型图有一个中心节点,并且恰有n-1条边将中心节点与其他每个节点连接起来。给你一个二维整数数组edges,其中 edges[i]=[ui,vi]表示在节点ui和vi之间存在一条边。请你找出并返回 edges所表示星型图的中心......
  • 根据多边形的坐标点计中心点的方法
    由于项目需要在地图覆盖物中心增加一个标签,我在网上找到一个算法来根据多边形的坐标点来计算得出该图像的中心点,在此记录一下。varfindCenter=function(points){varpoint_num=points.length;//坐标点个数varX=0,Y=0,Z=0;for(l......