Eureka分类:
Eureka工作机制
1) 服务注册中心
2) 服务对象
服务提供者
服务消费者
使用IDEA新建一个SpringBoot项目,选择如下依赖。(Eureka Server依赖自动依赖Spring Web,故可以不选择此项)
将配置文件改为yml后缀,做如下配置:
server:
port: 8761
spring:
application:
# 应用名称,Eureka 注册界面显示的名称(默认全大写)
name: SpringCloud-Eureka
# 配置security账号密码,Eureka服务中心引入Security后,必须手动关闭CRFS验证
security:
user:
name: admin
password: 123456
eureka:
instance:
# 应用实例主机名
hostname: localhost
server:
# 是否开启自我保护,默认为 true
# 当Eureka服务器在短时间内丢失过多客户端时,自我保护模式可使服务端不再删除失去连接的客户端
enable-self-preservation: false
client:
# 是否注册到 Eureka 服务中心,默认为true
register-with-eureka: false
# 是否拉取 Eureka 服务中心信息,默认为true
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
启动类上加上@EnableEurekaServer,启动项目,浏览器访问:http://localhost:8761, 得到如下界面说明配置成功
前面输入URL就能获取我们的Eureka Server信息,肯定是不安全的,这里我们加入Spring Security安全验证,来保证安全。
pom中新增依赖:
org.springframework.boot
spring-boot-starter-security
配置文件中新增如下配置:
spring:
# 配置security账号密码,Eureka服务中心引入Security后,必须手动关闭CRFS验证
security:
user:
# 账号、密码信息
name: admin
password: 123456
关闭Security默认启用的CSRF检验:
/**
* 关闭Security默认启用的CSRF检验
* Spring Security 4开始,默认启用CSRF机制,但是这会导致 Eureka客户端注入失败,
* 故需将其CSRF检验设置为false,来保障 Eureka客户端正常注入
* @author czm
* @date 2021/3/15
*/
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
/**
* 直接关闭CSRF检验,此外还可以通过 ignoringAntMatchers(uri) 的方式来部分关闭CSRF检验,如下
* http.csrf().ignoringAntMatchers("/eureka/**");
*/
http.csrf().disable();
super.configure(http);
}
}
重启项目,再次访问http://localhost:8761,会跳到登录界面,如下,账号密码就是上面配的 admin :123456,输入登录即可。
或者你图方便,可以像Eureka服务中心一样,只引入server依赖,应为其自动依赖于上面的这两个依赖:
server:
port: 8000 # 端口
spring:
application:
name: SpringCloud-EurekaClient # 应用名称
eureka:
client:
service-url:
# Eureka地址,当Eureka服务中心没有使用Spring Security时,可以去掉admin:123456,否则必须加上,不然该项目会注入失败
defaultZone: http://admin:123456@localhost:8761/eureka/
启动类新增@EnableEurekaClient或者@EnableDiscoveryClient(如果选用的注册中心是eureka,那么就推荐@EnableEurekaClient,如果是其他的注册中心,那么推荐使用@EnableDiscoveryClient。),启动项目,访问http://localhost:8761:
Spring Cloud Config是一个解决分布式系统的配置管理方案,为分布式系统外部化配置提供了支持,包含Config Server和Config Client两部分,Server提供配置文件存储,对外提供接口以获取配置文件的内容,Client通过接口获取数据,并初始化自己。
在Git上新建仓库文件
文件名spring-cloud-client-a-dev.yml由三部分组成:
这里的spring-cloud-client-a就是项目名称,dev就是环境,后缀也可以换位properties
server:
port: 8762
spring:
application:
name: SpringCloud-Config
cloud:
config:
server:
git:
# 远程Git地址,加不加.git后缀都行
uri: https://gitee.com/chenzm_ob/spring-cloud-config-resource
# 查找目录,即再该地址下的那个目录中去找我们的紫云
search-paths: resource
# 账号密码,私有仓库必须配置,共有仓库可以为空
username:
password:
# 资源分支,默认就为master
default-label: master
启动类上新增@EnableConfigServer注解,启动项目,访问设置的资源,格式如下:
# 不加label默认为master分支
/{application}/{profile}[/{label}]
/{label}/{application}-{profile}.yml
如:
http://localhost:8762/spring-cloud-client-a/dev/master
http://localhost:8762/master/spring-cloud-client-a-dev.yml
第一种方式获取到的内容如下,文件里的内容再source中。
{
"name":"spring-cloud-client-a",
"profiles":[
"dev"
],
"label":null,
"version":"22c4bcb8b3098502f97f7774b95b96174408e4a8",
"state":null,
"propertySources":[
{
"name":"https://gitee.com/chenzm_ob/spring-cloud-config-resource/file:E:\Cache\Temp\config-repo-6299963860127397661\resource\spring-cloud-client-a-dev.yml",
"source":{
"name":"czm",
"age":22,
"hobby.book":"Snowwalker",
"hobby.anime":"斗罗大陆",
"profile":"dev"
}
}
]
}
第二种方式获取到的数据格式于我们文件的格式一样,但是会有乱码,不过不重要,因为我们已经从Git上远程获取到资源了
name: czm
age: 22
hobby:
book: Snowwalker
anime: 鏂楃綏澶ч檰
profile: dev
客户端通过配置中心获取远程仓库数据。
创建项目后新增如下两个文件:
新增获取配置文件数据的对象:
@Component
public class ClientA {
// @Value 注解获取配置文件对应属性的值
@Value("${name}")
private String name;
@Value("${age}")
private int age;
@Value("hobby.book")
private String book;
@Value("hobby.anume")
private String anume;
@Value("${profile}")
private String profile;
// get/set 方法 或使用 lombok
}
新增测试接口:
@RestController
public class ClientAController {
// 注入ClientA对象
@Resource
private ClientA clientA;
@GetMapping("/getA")
public Object getClientA() {
return clientA;
}
}
由于我们需要从远程获取配置文件,然后从配置文件获取需要的数据,故这里除了常规的application.yml配置外,还需要一个bootstrap.yml配置文件。
Spring Boot服务启动时会加载application.yml/application.properties配置文件,Spring Cloud中有”引导上下文“的概念,引导上下文会加载bootstrap.yml/bootstrap.properties配置文件,即bootstrap.yml/bootstrap.properties会在Spring Boot服务启动之前加载,具有更高的优先级。默认情况下bootstrap.yml/bootstrap.properties中的属性不能被覆盖。
从Spring Boot 2.4版本开始,配置文件加载方式进行了重构。因此若要使用bootstrap.yml来进行配置,需要在pom中增加一个依赖,否则bootstrap.yml配置不生效:
org.springframework.cloud
spring-cloud-starter-bootstrap
bootstrap.yml配置文件:
spring:
application:
name: SpringCloud-ClientA1
profiles:
active: dev
cloud:
config:
uri: http://localhost:8762
name: spring-cloud-client-a
label: master
# 这种写法,当application.yml也设置了spring.profiles.active属性值时,该属性值会被替换,故实际获取的是application.yml中设置的active的值
profile: ${spring.profiles.active}
application.yml配置文件:
# 若两者都设置了同样的属性值,那么application.yml里的会覆盖调bootstrap.yml里的内容,如下面的spring.application.name
server:
port: 8763
spring:
application:
name: SpringCloud-ClientA
启动Config配置中心项目和客户端项目,访问客户端配置的getA接口: http://localhost:8763/getA
获取到如下数据,说明客户端获取远程仓库数据成功:
{"name":"czm","age":22,"book":"hobby.book","anume":"hobby.anume","profile":"dev"}
按微服务架构来说,所有需要注入到Eureka服务端的都是Eureka的客户端,所有需要获取远程仓库的服务都是Config客户端,故可以说除了Eureka服务端和Config服务端外,绝大多数服务都既是Eureka客户端,又是Config客户端,故需要兼顾这两者的配置。
我们先看下Config服务端接口Eureka的使用:
application.yml新增Eureka的服务中心地址:
eureka:
client:
service-url:
# 由于Eureka服务中心配置了Security账号密码,故所有需要注入到服务中心的客户端都要再URL中携带账号密码,如下
defaultZone: http://admin:123456@localhost:8761/eureka/
启动类也新增@EnableDiscoveryClient/@EnableEurekaClient,表示这是一个Eureka客户端服务,如示例的SpringCloud-Config项目模块。
application.yml新增Eureka的服务中心地址:
eureka:
client:
service-url:
# 由于Eureka服务中心配置了Security账号密码,故所有需要注入到服务中心的客户端都要再URL中携带账号密码,如下
defaultZone: http://admin:123456@localhost:8761/eureka/
启动类也新增@EnableDiscoveryClient/@EnableEurekaClient,表示这是一个Eureka客户端服务,如示例的SpringCloud-ClientA项目模块。
负载均衡分了两种类型:
客户端负载均衡(Ribbon)
服务端负载均衡(Nginx)
Spring Cloud Hystrix实现了断路器、线程隔离等一系列服务保护功能。
Hystrix提供几个熔断关键参数:滑动窗口大小(20)、 熔断器开关间隔(5s)、错误率(50%)
Spring Cloud Feign基于 Netflix Feign 实现,整合了 Spring Cloud Ribbon 与 Spring Cloud Hystrix, 除了整合这两者的强大功能之外,它还提 供了声明式的服务调用(不再通过RestTemplate)。
Spring Cloud OpenFeign在Feign的基础上支持了SpringMVC的注解,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
新建一个Eureka Client项目,加入openFeign依赖:
org.springframework.cloud
spring-cloud-starter-openfeign
普通的Eureka Client配置
server:
port: 8764
spring:
application:
name: service-openfeign
eureka:
client:
service-url:
defaultZone: http://admin:123456@localhost:8761/eureka
注入Restemplate:
@Configuration
public class RestemplateConf {
@Bean
@LoadBalanced // 开启负载均衡,URL使用服务名时必须加上此注解
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
新建两个Eureka Client项目(git中的SpringCloud-Eureka-B和SpringCloud-Eureka-C项目),除了端口不一样后,其余部分都一样,都暴露出一个同样的接口,组成负载系统
yml配置如下:
server:
port: 8765 # 端口不同,另一个是8766
spring:
application:
name: provider #两个项目的服务名称必须一样
eureka:
client:
service-url:
defaultZone: http://admin:123456@localhost:8761/eureka
暴露的接口,return的返回值有细微差别:
@RestController
@RequestMapping("/openFeign")
public class OpenFeignClientController {
@GetMapping("/test")
public Object openFeignTest() {
return "Spring Cloud 服务提供者——B,端口:8765";
}
}
OpenFeign 项目
添加OpenFeign接口:
@FeignClient("provider") // Eureka中的服务名
public interface OpenFeign {
@GetMapping("/opnefeign/test") // 指定服务中的某一个接口,直接通过 FeignInterface.test() 调用该接口
String openFeignTest();
}
PS:这里接口的返回值用的是String,如果改为Object会后面测试时报错:Could not extract response: no suitable HttpMessageConverter found for response type [class java.lang.Object] and content type [text/plain;charset=UTF-8]
具体原因还不清楚,如果有大佬知道还请不吝赐教!
添加OpenFeign测试接口:
@RestController
public class OpenFeignController {
@Resource
OpenFeign openFeign;
@GetMapping("/test")
public Object test() {
return openFeign.openFeignTest();
}
}
依次启动Eureka服务端项目、两个Eureka Client项目(B和C),最后启动类上新增**@EnableFeignClients**注解(开启 feign 功能)启动OpenFeign项目,浏览器访问test接口:http://localhost:8764/test,不断刷新页面,会发现页面内容是8765端口和8766端口返回的内容,两者交替出现,这就实现了一个简单的负载均衡。
网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过 网关这一层。也就是说,API 的实现方面更多地考虑业务逻辑,而安全、性能、监控可以交由 网关来做,这样既提高业务灵活性又不缺安全性。
优点:
安全 ,只有网关系统对外进行暴露,微服务可以隐藏在内网,通过防火墙保护。
易于监控。可以在网关收集监控数据并将其推送到外部系统进行分析。
易于认证。可以在网关上进行认证,然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。
减少了客户端与各个微服务之间的交互次数。
易于统一授权。
新建一个Eureka Client项目,pom中添加gateway依赖:
org.springframework.cloud
spring-cloud-starter-gateway
配置文件内容:
server:
port: 8790
spring:
application:
name: service-gateway
cloud:
gateway:
# 开启网关
enabled: true
discovery:
locator:
# 开启自动路由,以服务名建立路由
enabled: true
# 将服务名改为小写,否则url中指定服务名时必须大写
lower-case-service-id: true
eureka:
client:
service-url:
defaultZone: http://admin:123456@localhost:8761/eureka
通过网关访问服务接口URL的格式:http://网关地址:网关端口/服务名/服务对外提供的URL
启动Eureka服务中心,再任意启动一个Eureka客户端(这里我启动的是端口为8766的ClientC项目)和网关项目,分别访问http://localhost:8766/openFeign/test 和 http://localhost:8790/provider/openFeign/test,可以看的,两个页面显示的内容是一样的,说明实际访问的接口是一个接口。