微服务实战02-EurekaServer注册中心

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
云原生网关 MSE Higress,422元/月
简介: EurekaServer ,它扮演的角色是注册中心,用于注册各种微服务,以便于其他微服务找到和访问。

1、Eureka是什么

Eureka是Netflix的一个子模块,也是核心模块之一。Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。服务注册与发现对于微服务架构来说是非常重要的,有了服务发现与注册,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了。功能类似于dubbo的注册中心,比如Zookeeper。


Spring Cloud封装了Netflix公司开发的Eureka模块来实现服务注册和发现(请对比Zookeeper)


Eureka采用了C-S的设计架构,包含两个组件:Eureka Server 和 Eureka Client。Eureka Server作为服务注册功能的服务器,它是服务注册中心。各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。Eureka Client是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳。Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)


而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行。Spring Cloud的一些其他模块(比如Zuul)就可以通过Eureka Server来发现系统中的其他微服务,并执行相关的逻辑。


2.Eureka和Zookeeper

Zookeeper保证CP(C表示一致性)


当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。但是zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30~120s,且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因为网络问题使得zk集群失去master节点是较大概率会发生的事情,虽然服务器能最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。


Eureka保证AP(A表示可用性)


Eureka看明白了这一点,因此在设计时就优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册时如果发现连接失败,则会自动切换至其他节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:


(1)Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务


(2)Eureka依然能接受新服务的注册和查询请求,但是不会被同步到其他节点上(即保证当前节点依然可用)


(3)当网络稳定时,当前实例新的注册信息会被同步到其他节点中


因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像Zookeeper那样使整个注册服务瘫痪。


2.快速入门

我们将对上一节的项目进行改造,引入Eureka注册中心。


直观的感受就是,加一个模块Eureka服务器,独立运行起来,作为所谓的注册中心。


2.1 父项目改造

我们首先要对父项目改造,先删掉src目录,因为父项目是一个pom工程,没有代码,自然也就不需要src了

33.png

pom.xml增加对springbootd的依赖

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/>
    </parent>

设置一些依赖的编号,用properties节点,其中包含了spring-cloud的版本,我们选用Finchley.RELEASE

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>

增加一个依赖,用来测试:

<dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
</dependency>

设置给子模块继承的依赖。

<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>

<scope>import</scope>的意思是把父项目spring-cloud-dependencies里面的dependencyManagement导入(import)到本项目(parent)中,这种写法就不需要继承spring-cloud-dependencies了,因为本项目依据继承了spring-boot-starter-parent项目了,不能多继承吗,所以采用这种方式。


我们可以通过这种方式来实现版本号的统一。


通常工程比较庞大,模块多的时候,在pom.xml文件中,也就是父依赖中会看到dependencyManagement标签。这个标签的作用是:


①对项目所依赖jar包进行版本管理的管理器。


②使用pom.xml中的dependencyManagement元索能让所有在子模块中引用一个依赖而不用显式的列出版本号。也就是子模块不需要列出版本,子模块中的pom依赖会找到dependencyManagement所在jar包的版本,并引用这个jar对应的版本号。


③让子模块不在受繁杂的版本影响,和父pom中的依赖一致。


2.2 创建子项目eureka-server

34.png

项目 pom.xml ,增加 spring-cloud-starter-netflix-eureka-server jar 包

<dependencies>
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
      </dependency>
  </dependencies>

引入了spring-cloud-starter-netflix-eureka-server这个jar,但是我们没写版本号,这是因为parent项目导入了spring-cloud-dependencies里面的dependencyManagement。


spring-cloud-dependencies里面的dependencyManagement中又有一个spring-cloud-netflix-dependencies。


<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-netflix-dependencies</artifactId>
    <version>${spring-cloud-netflix.version}</version>
    <type>pom</type>
    <scope>import</scope>
   </dependency>

spring-cloud-netflix-dependencies中就有spring-cloud-starter-netflix-eureka-server这个依赖。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    <version>${project.version}</version>
   </dependency>

所以,当你不写版本号的话,这个版本肯定是在某个父项目中定义了。

子项目eureka-server的pom文件中,我们只需要增加 spring-cloud-starter-netflix-eureka-server jar 包即可。

2.3 EurekaServerApplication启动类


因为eureka-server本身就是一个SpringBoot项目,所以我们还是要写个启动类的,灯塔跑起来就可以注册服务了。


我们要启动服务,那么就需要加一个@SpringBootApplication,而@EnableEurekaServer 表示这是个 EurekaServer ,即注册中心。

public static void main(String[] args) {
 //8081 这个端口是默认的,就不要修改了,后面的子项目,都会访问这个端口。
 //不要写在yml文件里了,端口号可以直接在这里写死
    int port = 8081;
    //判断端口是否被占用
    if(!NetUtil.isUsableLocalPort(port)) {
        System.err.printf("端口%d被占用了,无法启动%n", port );
        System.exit(1);
    }
    //启动的时候配置端口号
    new SpringApplicationBuilder(EurekaServerApplication.class).
                properties("server.port=" + port)
                 .run(args);
}


2.4 EurekaServer配置文件

虽然我们把端口号写死在了代码中,但是这并不代表我们不需要写配置文件哈。

35.png


新建这样一个文件,内容如下:

eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
spring:
  application:
    name: eureka-server

hostname代表主机名称,因为我们是本地起服务,那么就是localhost。


registerWithEureka代表是否注册到服务器,EurekaServer本身就是服务器,自然是false。


fetchRegistry表示是否获取服务器的注册信息,EurekaServer本身就是服务器,自然是false。


defaultZone表示EurekaServer自己作为服务器,公布出来的地址。EurekaServer是注册中心,其他微服务要注册就需要知道往哪里注册,defaultZone就是干这个事情的。{server.port}虽然没有在yml文件中写明,但是启动的时候我们会带上,就是8081。所以地址就是http://localhost:8081/eureka/


启动EurekaServerApplication,访问http://localhost:8081/,注意,不是访问http://localhost:8081/eureka/,这个是公布出去的地址,不是EurekaServer本身的网页地址。


36.png


看到这个页面就成功了。


这就是注册中心的管理界面,主要看 :Instances currently registered with Eureka, 可以发现信息是:No instances available。


这表示,暂时还没有微服务注册进来。


下一节,我们就会讲解如何注册微服务进来啦。


相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
14天前
|
Dubbo Java 应用服务中间件
微服务框架Dubbo环境部署实战
微服务框架Dubbo环境部署的实战指南,涵盖了Dubbo的概述、服务部署、以及Dubbo web管理页面的部署,旨在指导读者如何搭建和使用Dubbo框架。
67 17
微服务框架Dubbo环境部署实战
|
11天前
|
自然语言处理 Java 网络架构
解锁跨平台微服务新纪元:Micronaut与Kotlin联袂打造的多语言兼容服务——代码、教程、实战一次打包奉送!
【9月更文挑战第6天】Micronaut是一款轻量级、高性能的Java框架,适用于微服务开发。它支持Java、Groovy和Kotlin等多种语言,提供灵活的多语言开发环境。本文通过创建一个简单的多语言兼容服务,展示如何使用Micronaut及其注解驱动特性实现REST接口,并引入国际化支持。无论是个人项目还是企业应用,Micronaut都能提供高效、一致的开发体验,成为跨平台开发的利器。通过简单的配置和代码编写,即可实现多语言支持,展现其强大的跨平台优势。
24 2
|
12天前
|
运维 监控 持续交付
深入浅出:微服务架构的设计与实战
微服务,一个在软件开发领域如雷贯耳的名词,它代表着一种现代软件架构的风格。本文将通过浅显易懂的语言,带领读者从零开始了解微服务的概念、设计原则及其在实际项目中的运用。我们将一起探讨如何将一个庞大的单体应用拆分为灵活、独立、可扩展的微服务,并分享一些实践中的经验和技巧。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
39 3
|
20天前
|
监控 Cloud Native 开发者
云端精英的.NET微服务秘籍:Azure上的创新实战演练
【8月更文挑战第28天】在现代软件开发中,微服务架构通过分解应用程序提升可维护性和扩展性。结合Azure与.NET框架,开发者能轻松打造高效且易管理的云原生微服务。首先,使用Docker容器化.NET应用,并借助Azure Kubernetes Service(AKS)或Azure Container Instances(ACI)部署。为确保高可用性和伸缩性,可利用Azure Traffic Manager负载均衡及Azure Autoscale动态调整实例数。
22 0
|
21天前
|
消息中间件 SQL 关系型数据库
go-zero微服务实战系列(十、分布式事务如何实现)
go-zero微服务实战系列(十、分布式事务如何实现)
|
19天前
|
Kubernetes Cloud Native Docker
云原生之旅:从容器到微服务的架构演变
【8月更文挑战第29天】在数字化时代的浪潮下,云原生技术以其灵活性、可扩展性和弹性管理成为企业数字化转型的关键。本文将通过浅显易懂的语言和生动的比喻,带领读者了解云原生的基本概念,探索容器化技术的奥秘,并深入微服务架构的世界。我们将一起见证代码如何转化为现实中的服务,实现快速迭代和高效部署。无论你是初学者还是有经验的开发者,这篇文章都会为你打开一扇通往云原生世界的大门。
|
20天前
|
负载均衡 应用服务中间件 持续交付
微服务架构下的Web服务器部署
【8月更文第28天】随着互联网应用的不断发展,传统的单体应用架构逐渐显露出其局限性,特别是在可扩展性和维护性方面。为了解决这些问题,微服务架构应运而生。微服务架构通过将应用程序分解成一系列小型、独立的服务来提高系统的灵活性和可维护性。本文将探讨如何在微服务架构中有效部署和管理Web服务器实例,并提供一些实际的代码示例。
51 0
|
4天前
|
运维 Cloud Native Devops
云原生架构的崛起与实践云原生架构是一种通过容器化、微服务和DevOps等技术手段,帮助应用系统实现敏捷部署、弹性扩展和高效运维的技术理念。本文将探讨云原生的概念、核心技术以及其在企业中的应用实践,揭示云原生如何成为现代软件开发和运营的主流方式。##
云原生架构是现代IT领域的一场革命,它依托于容器化、微服务和DevOps等核心技术,旨在解决传统架构在应对复杂业务需求时的不足。通过采用云原生方法,企业可以实现敏捷部署、弹性扩展和高效运维,从而大幅提升开发效率和系统可靠性。本文详细阐述了云原生的核心概念、主要技术和实际应用案例,并探讨了企业在实施云原生过程中的挑战与解决方案。无论是正在转型的传统企业,还是寻求创新的互联网企业,云原生都提供了一条实现高效能、高灵活性和高可靠性的技术路径。 ##
12 3
|
12天前
|
存储 Java Maven
从零到微服务专家:用Micronaut框架轻松构建未来架构
【9月更文挑战第5天】在现代软件开发中,微服务架构因提升应用的可伸缩性和灵活性而广受欢迎。Micronaut 是一个轻量级的 Java 框架,适合构建微服务。本文介绍如何从零开始使用 Micronaut 搭建微服务架构,包括设置开发环境、创建 Maven 项目并添加 Micronaut 依赖,编写主类启动应用,以及添加控制器处理 HTTP 请求。通过示例代码展示如何实现简单的 “Hello, World!” 功能,并介绍如何通过添加更多依赖来扩展应用功能,如数据访问、验证和安全性等。Micronaut 的强大和灵活性使你能够快速构建复杂的微服务系统。
33 5
|
25天前
|
Kubernetes 安全 微服务
使用 Istio 缓解电信 5G IoT 微服务 Pod 架构的安全挑战
在5G电信领域,Kubernetes集群中部署微服务至关重要,但也带来了重大的安全挑战。Istio作为一个强大的开源服务网格,能有效地管理这些微服务间的通信,通过其控制平面自动将Sidecar代理注入到各微服务Pod中,确保了安全且高效的通信。Istio的架构由数据平面和控制平面组成,其中Sidecar代理作为Envoy代理运行在每个Pod中,拦截并管理网络流量。此外,Istio支持多种Kubernetes发行版和服务,如EKS等,不仅增强了安全性,还提高了应用性能和可观测性。
57 0
使用 Istio 缓解电信 5G IoT 微服务 Pod 架构的安全挑战