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系列& ...
随机推荐
- Java&Selenium 鼠标键盘及滚动条控制相关方法封装
一.摘要 本片博文主要展示在使用Selenium with java做web自动化时,一些不得不模拟鼠标操作.模拟键盘操作和控制滚动条的java代码 二.模拟鼠标操作 package util; im ...
- IIS配置web.config 将带www域名转为不带www域名
在configuration节点中添加 <configuration> <system.webServer> <rewrite> <rules> < ...
- 推荐几款好用的Chrome插件
'工欲善其事,必先利其器'.优秀的开发者不仅体现在其在技术方面的精通,还体现在其对各种开发工具的充分了解与使用,这会让其开发效率事半功倍.作为一个前端开发者,平时主要是跟浏览器打交道,Chrome浏览 ...
- docker化canal与canal-adapter
今日公司需求,需要将mysql更新实时同步到kafka中,后来又要将数据库中的一张表的变化实时同步到另一台mysql中,于是乎canal与canal-adapter紧急解决,其中踩了不少坑,下面为总结 ...
- php操作kafka
php操作kafka----可以参照网上的安装步骤,先安装ldkafka rdkafka,然乎启动zookeeper和kafka服务器 <?php //$conf = new Rdkafka\P ...
- 在js中获取 input checkbox里选中的多个值
思路:利用name属性值获取checkbox对象,然后循环判断checked属性(true表示被选中,false表示未选中).下面进行实例演示: 1.html中展示: <input type=& ...
- MyBatis注解Annotation介绍及Demo(转)
MyBatis可以利用SQL映射文件来配置,也可以利用Annotation来设置.MyBatis提供的一些基本注解如下表所示. 注解 目标 相应的XML 描述 @CacheNamespace 类 &l ...
- java中commons-beanutils的介绍(转)
1. 概述 commons-beanutil开源库是apache组织的一个基础的开源库.为apache中很多类提供工具方法.学习它是学习其它开源库实现的基础. Commons-beanutil中包 ...
- python镜像
国内镜像列表豆瓣: http://pypi.doubanio.com/simple清华: https://pypi.tuna.tsinghua.edu.cn/simple科大: https://mir ...
- Nginx 配置访问静态资源
做个简单的配置: 以txt/png/mp4结尾的请求都会按照如下规则寻找返回文件 关键词: location.root location ~ \.(mp4|png|txt) { root /usr/l ...