Eureka 系列一 - 入门及启动

本贴最后更新于 1471 天前,其中的信息可能已经物是人非

最好的学习方式就是阅读官方手册。

github:https://github.com/Netflix/eureka

Eureka 介绍

这里直接引用百度百科的介绍吧

Eureka 是 Netflix 开发的服务发现框架,本身是一个基于 REST 的服务,主要用于定位运行在 AWS 域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud 将它集成在其子项目 spring-cloud-netflix 中,以实现 SpringCloud 的服务发现功能。

Eureka 包含两个组件:Eureka Server 和 Eureka Client。

Eureka Server 提供服务注册服务,各个节点启动后,会在 Eureka Server 中进行注册,这样 EurekaServer 中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。

Eureka Client 是一个 java 客户端,用于简化与 Eureka Server 的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器

在应用启动后,将会向 Eureka Server 发送心跳,默认周期为 30 秒,如果 Eureka Server 在多个心跳周期内没有接收到某个节点的心跳,Eureka Server 将会从服务注册表中把这个服务节点移除(默认 90 秒)。

Eureka Server 之间通过复制的方式完成数据的同步,Eureka 还提供了客户端缓存机制,即使所有的 Eureka Server 都挂掉,客户端依然可以利用缓存中的信息消费其他服务的 API。综上,Eureka 通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。

Eureka High level Architecture

image.png

使用 spring-cloud 启动集群

与常见的 zookeeper 作为注册中心不同的是,eureka 是 AP 的实现方式,在保证可用性的前提下,牺牲了一致性来保证服务的稳定性。对于在网络条件等不太好的情况下,euraka 将是比 zookeeper 更好的选择。当然了,现在 eureka 只有 1.0 版本,之后 Netflix 已经不再维护了(和 Hystrix 一样,😳 )。

server 的启动也直接参照官方说明来了:https://docs.spring.io/spring-cloud-netflix/docs/current/reference/html/#spring-cloud-eureka-server

创建工程,引入依赖

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>

基本代码

package com.acssor.tengfei.registercenter; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }

simple properties

application.yml

server: port: 8888 eureka: instance: hostname: localhost client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

启动应用,查看控制台

http://localhost:8888/

image.png

注册一个服务

创建工程,引入依赖

这里偷懒了,很多依赖没有删除。大家看情况删除吧

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>29.0-jre</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>

基本代码

package com.acssor.tengfei.student; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @EnableEurekaClient @SpringBootApplication(scanBasePackages = "com.acssor.tengfei") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }

创建了一个 url 请求

package com.acssor.tengfei.student.web; import com.acssor.tengfei.student.bean.StudentBean; import com.acssor.tengfei.student.service.IStudentService; import com.acssor.tengfei.student.util.GSONUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; import org.springframework.validation.ObjectError; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.List; import java.util.stream.Collectors; @RestController @RequestMapping("/student") @Slf4j public class StudentController { @Resource private IStudentService studentService; @PostMapping public ResponseEntity save(@RequestBody @Validated StudentBean student, BindingResult bindingResult) { if (bindingResult.hasErrors()) { List<ObjectError> allErrors = bindingResult.getAllErrors(); String errMsg = allErrors.stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(",")); log.warn("students save error, invalid params, student:{}, error: {}", GSONUtils.toJson(student), errMsg); return new ResponseEntity(errMsg, HttpStatus.BAD_REQUEST); } studentService.saveOrUpdate(student); return new ResponseEntity(student, HttpStatus.OK); } }

simple properties

application.yml

spring: profiles: active: dev application: name: student-server datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:32769/tengfei?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true username: root password: root jpa: properties: hibernate: hbm2ddl: auto: create dialect: org.hibernate.dialect.MySQL5InnoDBDialect format_sql: true show-sql: true server: port: 10086 tomcat: uri-encoding: UTF-8 threads: max: 200 max-connections: 800 accept-count: 100 eureka: client: register-with-eureka: true # 是否注册自己的信息到EurekaServer,默认是true fetch-registry: true # 是否拉取其它服务的信息,默认是true service-url: defaultZone: http://localhost:8888/eureka # EurekaServer地址 #instance: #prefer-ip-address: true # 当调用getHostname获取实例的hostname时,返回ip而不是host名称 #ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找

启动关键日志

2021-05-05 23:16:24.003 INFO 32990 --- [ main] com.netflix.discovery.DiscoveryClient : Initializing Eureka in region us-east-1 2021-05-05 23:16:25.603 INFO 32990 --- [ main] com.netflix.discovery.DiscoveryClient : Disable delta property : false 2021-05-05 23:16:25.603 INFO 32990 --- [ main] com.netflix.discovery.DiscoveryClient : Single vip registry refresh property : null 2021-05-05 23:16:25.603 INFO 32990 --- [ main] com.netflix.discovery.DiscoveryClient : Force full registry fetch : false 2021-05-05 23:16:25.603 INFO 32990 --- [ main] com.netflix.discovery.DiscoveryClient : Application is null : false 2021-05-05 23:16:25.603 INFO 32990 --- [ main] com.netflix.discovery.DiscoveryClient : Registered Applications size is zero : true 2021-05-05 23:16:25.603 INFO 32990 --- [ main] com.netflix.discovery.DiscoveryClient : Application version is -1: true 2021-05-05 23:16:25.603 INFO 32990 --- [ main] com.netflix.discovery.DiscoveryClient : Getting all instance registry info from the eureka server 2021-05-05 23:16:25.963 INFO 32990 --- [ main] com.netflix.discovery.DiscoveryClient : The response status is 200 2021-05-05 23:16:25.968 INFO 32990 --- [ main] com.netflix.discovery.DiscoveryClient : Starting heartbeat executor: renew interval is: 30 2021-05-05 23:16:25.974 INFO 32990 --- [ main] c.n.discovery.InstanceInfoReplicator : InstanceInfoReplicator onDemand update allowed rate per min is 4 2021-05-05 23:16:25.981 INFO 32990 --- [ main] com.netflix.discovery.DiscoveryClient : Discovery Client initialized at timestamp 1620227785979 with initial instances count: 0 2021-05-05 23:16:25.987 INFO 32990 --- [ main] o.s.c.n.e.s.EurekaServiceRegistry : Registering application STUDENT-SERVER with eureka with status UP 2021-05-05 23:16:25.988 INFO 32990 --- [ main] com.netflix.discovery.DiscoveryClient : Saw local status change event StatusChangeEvent [timestamp=1620227785988, current=UP, previous=STARTING] 2021-05-05 23:16:25.999 INFO 32990 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_STUDENT-SERVER/xxxxxx:student-server:10086: registering service... 2021-05-05 23:16:26.080 INFO 32990 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 10086 (http) with context path '' 2021-05-05 23:16:26.081 INFO 32990 --- [ main] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 10086 2021-05-05 23:16:26.093 INFO 32990 --- [ main] DeferredRepositoryInitializationListener : Triggering deferred initialization of Spring Data repositories… 2021-05-05 23:16:26.174 INFO 32990 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_STUDENT-SERVER/xxxxxx:student-server:10086 - registration status: 204

控制台检查

image.png

注册一个调用者

创建工程,引入依赖

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>

基本代码

package com.acssor.tengfei.boot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication(scanBasePackages = "com.acssor.tengfei") @EnableZuulProxy public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }

入口访问地址:

配置文件

spring: profiles: active: dev server: port: 8080 tomcat: uri-encoding: UTF-8 threads: max: 200 max-connections: 800 accept-count: 100 #注册进eureka eureka: client: serviceUrl: defaultZone: http://localhost:8888/eureka/ #配置网关转发详情 zuul: routes: api-a: path: /student-proxy/** service-id: student-server # api-b: # path: /order/** # service-id: order-server

测试访问

localhost:8080/student-proxy/student/。因为服务端是 post 请求的定义,因此通过调用者代理,返回的将是 405

image.png

结束语

以上,一个完整的例子结束。后续将对 eureka 的详细配置做一个介绍,来说明各种配置参数的定义及适用场景是什么。

  • Eureka
    22 引用 • 3 回帖
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖 • 2 关注
  • 注册中心
    1 引用 • 1 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...