Spring Cloud(2):服务发现(Eureka)
Spring Cloud Eureka是Spring Cloud Netflix项目下的一个模块,作用是服务的注册和发现,并实现服务治理。它有一个(或一组,以实现高可用)服务注册中心(eureka server)并提供服务注册功能,所有的应用程序将作为服务提供方(eureka client)向eureka server注册服务,当应用程序之间相互调用时,不再通过IP地址调用,将通过eureka server,使用注册的service id来调用。
下面,分别从5个方面来讲Eureka:Eureka Server,Eureka Client,Peer Awareness,Securing The Eureka Server,Discovery Client。
(1)搭建Eureka Server
首先,创建一个SpringBoot Web Aplication,在pom.xml中加入spring-cloud-starter-netflix-eureka-server包。这里使用的是Spring Boot 2.2.5和Spring Cloud Hoxton.SR3。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <dependencies>
<!-- Spring cloud starter: netflix-eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
其次,在启动类ServerEurekaApplication中加入@EnableEurekaServer注解。
@SpringBootApplication
@EnableEurekaServer
public class ServerEurekaApplication {
public static void main(String[] args) {
SpringApplication.run(ServerEurekaApplication.class, args);
}
}
最后,在配置文件中配置Eureka信息。
bootstrap.yml
spring:
application:
name: server-eureka
application.yml
## Server info
server:
port:
servlet:
context-path: /server-eureka ## Eureka info
eureka:
instance:
hostname: localhost
# You need to change these, even for an Actuator application if you use a non-default context path or servlet path
# https://cloud.spring.io/spring-cloud-netflix/spring-cloud-netflix.html#_status_page_and_health_indicator
statusPageUrlPath: ${server.servlet.context-path}/actuator/info
healthCheckUrlPath: ${server.servlet.context-path}/actuator/health
client:
# 程序启动时不要通过Eureka注册服务,因为它本身就是Eureka服务
registerWithEureka: false
# 不会在本地缓存注册表信息
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/server-eureka/eureka/
# Eureka不会马上通知任何注册它的服务,默认情况下会等待5min。本地测试时应该注释掉此行,以加快程序运行
# 每次服务注册需要30s的时间才能显示在Eureka服务中,因为Eureka需要接收3此心跳包,每次间隔10s,然后才能使用这个服务。
#server:
# waitTimeInMsWhenSyncEmpty: 5
server:
waitTimeInMsWhenSyncEmpty:
(2)搭建Eureka Client
首先,创建一个SpringBoot Web Aplication,在pom.xml中加入spring-cloud-starter-netflix-eureka-client包。
<!-- Spring cloud starter: netflix-eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
然后,在配置文件中配置Eureka信息。
## Server Info
server:
port:
servlet:
context-path: /app-web ## Eureka info
eureka:
instance:
# You need to change these, even for an Actuator application if you use a non-default context path or servlet path
# https://cloud.spring.io/spring-cloud-netflix/spring-cloud-netflix.html#_status_page_and_health_indicator
statusPageUrlPath: ${server.servlet.context-path}/actuator/info
healthCheckUrlPath: ${server.servlet.context-path}/actuator/health
# 注册服务的IP而不是服务器名称
# preferIpAddress: true
client:
# 向Eureka注册服务(default is true)
registerWithEureka: true
# 拉取注册表的本地副本(default is true)
fetchRegistry: true
serviceUrl:
defaultZone: http://localhost:10000/server-eureka/eureka/
[注1] preferIpAddress:在默认情况下,Eureka注册服务使用了主机名与外界联系,这种方式在服务器环境中是OK的,因为通过DNS可以解析成IP地址。但是,在基于容器的部署环境中(如Docker),主机名是随机生成的,且并没有DNS记录。将eureka.instance.preferIpAddress设置为true,当应用程序向eureka注册时,它使用其IP地址而不是其主机名。
如果设置eureka.instance.prefer-ip-address为false时,那么注册到Eureka中的IP地址就是本机的IP地址。如果设置了true并且也设置了eureka.instance.ip-address那么就将此ip地址注册到Eureka中。那么调用的时候,发送的请求目的地就是此Ip地址。
参考:
https://www.jianshu.com/p/886947b52cb4
[注2] 从Spring Cloud Edgware开始,@EnableDiscoveryClient或@EnableEurekaClient可省略。只需加上相关依赖,并进行相应配置,即可将微服务注册到服务发现组件上。Spring Cloud中的Discovery Service有多种实现,比如:eureka,consul,zookeeper。
- @EnableDiscoveryClient 注解是基于spring-cloud-commons依赖,并且在classpath中实现
- @EnableEurekaClient 注解是基于spring-cloud-netflix依赖,只能为eureka作用
如果你的classpath中添加了eureka,则它们的作用是一样的。
(3)Peer Awareness(高可用的Eureka集群)
假设我们现在有3台Eureka Server,IP地址分别为:192.168.0.1,192.168.0.2,192.168.0.3。配置文件修改如下:
application-peer1.yml
## Eureka info
eureka:
instance:
# http://cloud.spring.io/spring-cloud-netflix/spring-cloud-netflix.html#spring-cloud-eureka-server-peer-awareness
hostname: 192.168.0.1
client:
# 需要修改下面两个配置,让注册中心可以向另外一个注册中心注册服务,以实现高可用
registerWithEureka: true
fetchRegistry: true
# 向另2个Eureka Server注册自己
serviceUrl:
defaultZone: http://192.168.0.2:10000/server-eureka/eureka/,http://192.168.0.3:10000/server-eureka/eureka/
application-peer2.yml
eureka:
instance:
hostname: 192.168.0.2
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://192.168.0.1:10000/server-eureka/eureka/,http://192.168.0.3:10000/server-eureka/eureka/
application-peer3.yml
eureka:
instance:
hostname: 192.168.0.3
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://192.168.0.1:10000/server-eureka/eureka/,http://192.168.0.2:10000/server-eureka/eureka/
当我们在Eureka Client中向Eureka Server注册时,需要修改配置文件如下:
eureka:
client:
serviceUrl:
defaultZone: http://192.168.0.1:10000/server-eureka/eureka/,http://192.168.0.2:10000/server-eureka/eureka/,http://192.168.0.3:10000/server-eureka/eureka/
(4)使用Spring Security保护Eureka Server
首先,在pom.xml中加入spring-cloud-starter-netflix-eureka-client包。
<!-- Spring cloud starter: security -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
然后,添加一个user和password用于登录Eureka Server自带的页面:http://{host}:{port}/server-eureka。值得注意的是,需要disable'/eureka/**'端点的csrf()。
@EnableWebSecurity
public class ServerEurekaWebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
} @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//@formatter:off
PasswordEncoder encoder = new BCryptPasswordEncoder();
auth.inMemoryAuthentication()
.withUser("eureka-user").password("{bcrypt}" + encoder.encode("eureka-user")).roles("USER");
//@formatter:on
} @Override
protected void configure(HttpSecurity http) throws Exception {
// By default when Spring Security is on the classpath,
// it will require that a valid CSRF token be sent with every request to the app.
// Eureka clients will not generally possess a valid cross site request forgery (CSRF) token,
// you will need to disable this requirement for the /eureka/** endpoints.
// https://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.1.2.RELEASE/single/spring-cloud-netflix.html#_securing_the_eureka_server
http.csrf().ignoringAntMatchers("/eureka/**");
super.configure(http);
}
}
最后,所有向Eureka Server注册的URL都要改成这样的形式:http://user:password@localhost:8761/eureka。
上面(3)中Eureka Server集群中的相互注册:
eureka:
username: eureka-user
password: '{cipher}72cd0bdd18c6928b025e9e5dfa94cce539b555c4b3364590c689df3532fa69bc'
client:
serviceUrl:
defaultZone: http://${eureka.username}:${eureka.password}@192.168.0.2:10000/server-eureka/eureka/,http://${eureka.username}:${eureka.password}@192.168.0.3:10000/server-eureka/eureka/
上面(3)中Eureka Client中的注册:
eureka:
username: eureka-user
password: '{cipher}72cd0bdd18c6928b025e9e5dfa94cce539b555c4b3364590c689df3532fa69bc'
client:
serviceUrl:
defaultZone: http://${eureka.username}:${eureka.password}@192.168.0.1:10000/server-eureka/eureka/,http://${eureka.username}:${eureka.password}@192.168.0.2:10000/server-eureka/eureka/,http://${eureka.username}:${eureka.password}@192.168.0.3:10000/server-eureka/eureka/
[注] 上面密码使用JCE(Java Cryptography Extension)的对称加密,这部分可以看 Spring Cloud(4):配置服务(Config)。
(5)在Eureka Client中使用Discovery Client来发现并调用其他Client服务
一个微服务架构中会有多个Eureka Client,当它们向Eureka Server注册后,就可以通过下面2种方法相互调用:
1. 使用EurekaClient(DiscoveryClient)
@Autowired
private EurekaClient discoveryClient; public String serviceUrl() {
InstanceInfo instance = discoveryClient.getNextServerFromEureka("app-name", false);
String path = String.format("http://%s:%s/aaa/bbb", instance.getHostName(), instance.getPort());
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(path, HttpMethod.GET, null, String.class);
return response.getBody();
}
2. 使用带有Ribbon功能的LoadBalancerClient(负载均衡)
@Autowired
private LoadBalancerClient loadBalancer; public String serviceUrl() {
ServiceInstance instance = loadBalancer.choose("app-db");
String path = String.format("http://%s:%s/aaa/bbb", instance.getHost(), instance.getPort());
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(path, HttpMethod.GET, null, String.class);
return response.getBody();
}
Hoxton.SR3
Spring Cloud(2):服务发现(Eureka)的更多相关文章
- Spring cloud 微服务架构 Eureka篇
1 服务发现 ## 关于服务发现 在微服务架构中,服务发现(Service Discovery)是关键原则之一.手动配置每个客户端或某种形式的约定是很难做的,并且很脆弱.Spring Cloud提供了 ...
- Spring Cloud 2-Eureka服务发现注册(一)
Spring Cloud Eureka 1.服务端配置 pom.xml application.yml Application.java 2.客户端配置 pom.xml application.ym ...
- 二、spring cloud 注册与发现eureka注册中心
基于2.0 Greenwich高可用eureka注册中心搭建 一.单机版 新建MAVEN父工程demo-parent 删掉src pom.xml <packaging>pom</pa ...
- Spring Cloud|高可用的Eureka集群服务
Eureka,作为spring cloud的服务发现与注册中心,在整个的微服务体系中,处于核心位置.单一的eureka服务,显然不能满足高可用的实际生产环境,这就要求我们配置一个能够应对各种突发情况, ...
- 用ZooKeeper做为注册中心搭建基于Spring Cloud实现服务注册与发现
前提: 先安装好ZooKeeper的环境,搭建参考:http://www.cnblogs.com/EasonJim/p/7482961.html 说明: 可以再简单的理解为有两方协作,一个是服务提供这 ...
- Spring Cloud 微服务的那点事
什么是微服务 微服务的概念源于2014年3月Martin Fowler所写的一篇文章“Microservices”. 微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调 ...
- spring cloud 学习(二)关于 Eureka 的学习笔记
关于 Eureka 的学习笔记 个人博客地址 : https://zggdczfr.cn/ ,欢迎光临~ 前言 Eureka是Netflix开发的服务发现组件,本身是一个基于REST的服务.Sprin ...
- Spring Cloud 微服务一:Consul注册中心
Consul介绍 Consul is a service mesh solution providing a full featured control plane with service disc ...
- Spring Cloud (1) 服务的注册与发现(Eureka)
Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全 ...
- Spring cloud实现服务注册及发现
服务注册与发现对于微服务系统来说非常重要.有了服务发现与注册,你就不需要整天改服务调用的配置文件了,你只需要使用服务的标识符,就可以访问到服务. 本文属于<7天学会spring cloud系列& ...
随机推荐
- linux下top命令的使用
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器 视图参数含义 top视图分为两部分:操作系统资源概况信息和进程信息.首先分析资源 ...
- idea将普通目录转换为模块maven module。
假如你想把aaa这个目录改为像common一样的Module,在aaa目录下新建一个同名的aaa.iml,然后粘贴这段代码 <?xml version="1.0" encod ...
- Sleep-Join方法理解
package cn.mayday.test; public class JoinTest { public static void main(String[] args) { try { int c ...
- solr 中文分词相关(转载)
smartcn和ik的对比,来自http://www.cnblogs.com/hadoopdev/p/3465556.html 一.引言: 年的时候,就曾经有项目涉及到相关的应用(Lunce构建全文搜 ...
- 11 canvas 画布 - 基础
一.概述 canvas它和其它的HTML5标签的使用基本一致,但是它相当于在浏览器中建立一个画布,可以再这个画布上画图.创建动画甚至是3D游戏.由于canvas要适配不同终端的分辨率,所以尽可能的在标 ...
- codeblock的一个小问题
也许不叫问题吧,也可能是编译器的特性. 我的codeblock选择的编译器: 编写.cpp文件时,floatl类型输入输出都是 %f,double类型输入只能是 %lf,输出只能是 %f. 但是在co ...
- Enable file editing in Visual Studio's debug mode
Visual Studio 使用及调试必知必会 http://www.cnblogs.com/luminji/p/3287728.html How do I enable file editing i ...
- JSP大文件分片上传
核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...
- IntelliJ IDEA 创建 Git 分支并且 Push 到远程
在 IntelliJ 的右下角,你可以看到当前的 Git 分支,然后你可以单击这个分支后,在弹出的界面的最上方有一个新建分支的选项. 然后再弹出的界面中,输入你要创建的分支名称后回车输入. 然后从项目 ...
- hdu 4998 Rotate 点的旋转 银牌题
Rotate Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...