首先提醒一下,Spring Cloud和Spring Boot的版本非常重要一定要匹配
这里使用Spring Cloud的F版本和Spring Boot的2.0.3.Release版本
一.eureka服务注册中心
1.注册中心
用idea创建一个spring initializr项目
pom:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
在启动类上添加@EnableEurekaServer注解表明这是一个Eureka的服务类
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
application.yml如下
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
spring:
application:
name: eurka-server
registerWithEureka和fetchRegistry设为false,表明这是提供注册的Eureka服务。
启动服务,访问http://localhost:8761
2.服务提供者
再创建一个同样的项目pom一样,将启动类的@EnableEurekaServer改为@EnableEurekaClient,这是一个注册到Eureka上的服务提供者
application.yml:
server:
port: 8763
spring:
application:
name: service-offer
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
然后可以自己编写一个接口,启动后会发现Eureka界面上多了这个服务,这样服务提供者就注册到服务注册中心上了
3.整合Actuator
在上面的项目的pom.xml中添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
然后启动后访问localhost:8762/actuator 可以得到
这是actuator暴露的端点列表,里面的href都是可以访问的
actuator有以下常用的端点:
端点 | 描述 | HTTP方法 |
autoconfig | 显示自动配置信息 | GET方法 |
beans | 显示应用程序上下文所有的spring bean | GET方法 |
configgrops | 显示所有@ConfigurationProperties的配置属性列表 | GET方法 |
dump | 显示线程活动的快照 | GET方法 |
env | 显示应用的环境变量 | GET方法 |
health | 显示应用程序的健康指标,这些值由HealthIndicator的实现类提供 | GET方法 |
info | 显示应用程序的信息,可使用info.*属性自定义info端点公开的数据 | GET方法 |
mappings | 显示所有的URL路径 | GET方法 |
metrics | 显示应用的度量标准信息 | GET方法 |
shutdown | 关闭应用(默认情况下不使用,如需启用,需设置endpoints.shutdown.enabled=true) | POST方法 |
trace | 显示跟踪信息(默认情况下为最近100个HTTP请求) | GET方法 |
在application.yml中加入以下:
info:
app:
name: @project.artifactId@
encoding: @project.build.sourceEncoding@
java:
source: @java.version@
target: @java.version@
然后再重启服务并访问localhost:8762/actuator/info,得到如下:
默认暴露的HTTP端点是health和info,可以在application.yml加入如下代码,修改暴露的HTTP端点:
management:
endpoints:
web:
exposure:
include: health,info,env
重启红localhost:8762/actuator/env就可以访问了。
health端点默认只显示简单的UP,表示健康,加入以下可以让health显示数据库和磁盘详细信息
management:
endpoint:
health:
show-details: always
使用Actuator可以方便查看服务信息。
4.Eureka的高可用
注册中心修改
将Eureka注册中心的application.yml修改如下
server:
port: 8762
eureka:
instance:
hostname: localhost
client:
#registerWithEureka: false
#fetchRegistry: false
serviceUrl:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: eurka-server
启动后再修改application.yml再启动一个Eureka Server的服务(前一个不要停掉)
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
#registerWithEureka: false
#fetchRegistry: false
serviceUrl:
defaultZone: http://localhost:8762/eureka/
spring:
application:
name: eurka-server
这样8761和8762两个Eureka Server就做了集群并互相注册
服务提供者修改
将application.yml的eureka节点修改如下即可:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
5.Eureka用户认证
注册中心修改
添加配置类,这是为了覆盖默认的配置,spring cloud 2.0会启用csrf认证,在这里取消掉
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
super.configure(http);
}
}
修改Eureka Server的 application.yml
spring:
application:
name: eurka-server
security:
basic:
enabled: true
user:
name: admin
password: pwd
启动并访问localhost:8761会跳转到登录界面
输入用户名密码即可
注册服务修改
将要注册的服务的application.yml中的defaultZone改成:
eureka:
client:
serviceUrl:
defaultZone: http://admin:pwd@localhost:8761/eureka/
6.服务消费者
新建一个springboot项目,pom依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
application.yml:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8764
spring:
application:
name: service-ribbon
配置restTemplate:
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
然后编写controller和service,service代码如下:
@Autowired
RestTemplate restTemplate;
@Override
public String hiService(String name) {
return restTemplate.getForObject("http://localhost:8763/test,String.class);//访问服务提供者的接口
}
启动服务消费者,访问接口即可从服务提供者获取需要的接口数据
7.Eureka元数据
分为标准元数据和自定义元数据,标准元数据包括ip、端口号、主机名等,自定义元数据通过application.yml中的metadata-map设置。
修改服务提供者的application.yml:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
#这是暴露IP给服务注册中心,不设置的话暴露的是hostname
perfer-ip-address: true
metadata-map:
mydata: this-is-my-data
在上面定义了一个叫mydata的自定义元数据
修改服务消费者的,在controller增加如下代码:
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping(value = "/instanceInfo")
public List<ServiceInstance> showInfo() {
return discoveryClient.getInstances("service-offer");
}
启动注册中心、服务提供者、服务消费者,访问localhost:8764/instanceInfo就可以得到如下元数据。
[
{
"host": "localhost",
"port": 8763,
"metadata": {
"mydata": "this-is-my-data",
"management.port": "8763",
"jmx.port": "55654"
},
"secure": false,
"uri": "http://localhost:8763",
"instanceInfo": {
"instanceId": "localhost:service-offer:8763",
"app": "SERVICE-HI",
"appGroupName": null,
"ipAddr": "192.168.157.1",
"sid": "na",
"homePageUrl": "http://localhost:8763/",
"statusPageUrl": "http://localhost:8763/actuator/info",
"healthCheckUrl": "http://localhost:8763/actuator/health",
"secureHealthCheckUrl": null,
"vipAddress": "service-hi",
"secureVipAddress": "service-hi",
"countryId": 1,
"dataCenterInfo": {
"@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
"name": "MyOwn"
},
"hostName": "localhost",
"status": "UP",
"overriddenStatus": "UNKNOWN",
"leaseInfo": {
"renewalIntervalInSecs": 30,
"durationInSecs": 90,
"registrationTimestamp": 1550817775929,
"lastRenewalTimestamp": 1550817895862,
"evictionTimestamp": 0,
"serviceUpTimestamp": 1550817775929
},
"isCoordinatingDiscoveryServer": false,
"metadata": {
"mydata": "this-is-my-data",
"management.port": "8763",
"jmx.port": "55654"
},
"lastUpdatedTimestamp": 1550817775929,
"lastDirtyTimestamp": 1550817775855,
"actionType": "ADDED",
"asgName": null
},
"serviceId": "SERVICE-HI",
"scheme": null
}
]