Spring Cloud 微服务实践
image.png这本书的作者是我的同事, 有幸拜读了这一本书, 我一定要好好做笔记
Spring Cloud 基础知识
Spring Cloud 家族
版本号
Spring Boot
- 构建: 通过官方的Spring Initializr工具(https://start.spring.io/)产生基础项目
Spring Boot Starter
实现RESTful API
- Controller层定义
// @RestController = @Controller + @ResponseBody
@RestController
public class HelloController{
@RequestMapping("Hello")
public String index(){
return "Hello World";
}
}
启动Spring Boot应用
- 运行main函数
mvn spring-boot:run
-
mvn install
后,执行java -jar xxx.jar
单元测试
// 引入Spring对JUnit4的支持
@RunWith(SpringJUnit4ClassRunner.class)
// 指定Spring Boot的启动类,或@SpringBootTest(classes=Bootstrap.class)
@SpringApplicationConfiguration(classes=HelloApplication.class)
// 开启Web应用的配置,用于模拟ServletContext
@WebAppConfiguration
public class HelloApplicationTests{
// 用于模拟调用Controller的接口发起请求
private MockMvc mvc;
@Before
public void setUp() throws Exception{
// 初始化对HelloController的模拟
mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
}
@Test
public void hello() throws Exception{
// perform执行一次调用请求
mvc.perform(MockMvcRequestBuilders.get("/hello")
.accept(MediaType.APPLICATION_JSON)) // 用于执行接收的数据类型
.andExpect(status().isOk()) // 接口返回的期望值
.andExpect(content().string(equalTo("Hello World")));
}
}
配置详解
配置文件
# application.properites文件
# 指定应用名(在Spring Cloud中会被注册为服务名)
spring.application.name=hello
-
Spring Boot 的配置文件除了可以使用传统对properites文件,还支持被广泛推荐使用的YAML文件“application.yml ”。yaml缺点是无法通过@PropertySource注解来加载配置。但YAML将属性加载到内存时有序的。所以当配置中的信息需要顺序时,YAML更有优势
environments: dev: url: http://dev.bar.com name: Developer Setup prod: url: http://foo.bar.com name: My Cool App
上面等价于properties
environments.dev.url = http://dev.bar.com environments.dev.name = Developer Setup environments.prod.url = http://foo.bar.com environments.prod.name = My Cool App
除此之外,YAML还可以在一个单文件中通过使用spring.profiles属性来定义多个不同的环境配置
# 没有指定环境,则使用8081端口 server: prot: 8081 --- # 指定test环境,则使用8082端口 spring: profiles: test server: prot: 8082 --- # 指定prod环境,则使用8083端口 spring: profiles: prod server: prot: 8083
自定义参数
-
application.properties中可以添加自定义属性
book.name=SpringCloudInAction book.author=Luyunfei # 可以直接引用上面定义的参数值 book.desc = ${book.author} is writing ${book.name} # 使用${random}配置可产生随机的int, long, string字符串 # ${random.value} 随机字符串 # ${random.int} 随机int # ${random.long} 随机long # ${random.int(10)} 10以内的随机数 # ${random.int[10,20]} 10~20的随机数 book.port = ${random.value}
然后在应用中通过@Value注解来加载这些自定义参数
@Component public class Book{ @Value("${book.name}") private String name; }
命令行参数
命令行优先于配置 java -jar xxx.jar --server.port=8888
多环境配置
- 文件名需要满足application-{profile}.properties格式
- application-dev.properties
- application-test.properties
- application-prod.properties
- 具体使用哪个文件,需要在application.properties文件中通过
spring.profiles.active=prod
定义
监控与管理
spring-boot-starter-actuator 能够为Spring Boot构建的应用提供一系列用于监控的端点。同时,Spring Cloud在实现各个微服务组件的时候,进一步为该模块做了不少扩展。
-
增加
spring-boot-starter-actuator
依赖, 模块会根据应用依赖和配置自动创建初监控和管理端点<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
-
通过访问上图中的端点,可以实时获取相应的信息。引入Spring Cloud的各个组件后,返回信息会变得更加丰富
原生端点
根据端点的作用,将原生端点分为以下三大类
- 应用配置类: 获取应用程序中加载的应用配置,环境变量,自动化配置报告等与Spring Boot应用密切相关的配置类信息。(静态报告)
- 度量指标类: 获取应用运行过程中用于监控的度量指标,比如:内存信息,线程池信息,HTTP请求统计等。(动态报告)
- 操作控制类: 提供了对应用的关闭等操作类功能
类型 | 端点 | 说明 |
---|---|---|
应用配置类 | /autoconfig |
获取应用的自动化配置报告,帮助我们方便地找到一些自动化配置为什么没有生效的具体原因。 1. 返回字段 positiveMatches: 条件匹配成功的自动化配置 2. 返回字段 negativeMatches: 条件匹配不成功的自动化配置 |
应用配置类 | /beans |
获取应用上下文中创建的所有Bean |
应用配置类 | /configprops |
获取应用中配置的各个属性 |
应用配置类 | /env |
获取应用中所有可用的环境属性, 如环境变量,JVM属性,应用的配置属性,命令行中的参数等。密码等敏感信息,会使用*来替代实际的属性值。配合spring security可以屏蔽敏感信息 |
应用配置类 | /mappings |
获取Spring MVC的控制器映射关系报告,即url对应哪个controller的什么方法 |
应用配置类 | /info |
获取应用application.properties文件中添加info前缀的自定义信息,例如info.app.name=spring-demo
|
度量指标类 | /metrics |
获取当前应用内存信息,线程信息,垃圾回收信息等。/metrics/{name} 查询某一项信息,例如/metrics/mem.free 查询当前可用内存数量 |
度量指标类 | /health |
各类健康指标信息,如低磁盘空间检测,DataSource连接是否可用,Mongo数据库是否可用,Redis服务器是否可用等 |
度量指标类 | /dump |
程序运行中的线程信息 |
度量指标类 | /trace |
基本的HTTP跟踪信息 |
操作控制类 | /shutdown |
远程控制关闭当前应用 |
Spring Cloud Eureka(类似于Zookeeper,Consul)
搭建服务注册中心
引入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.7.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.3.7.RELEASE</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
标注@EnableEurekaServer
@EnableEurekaServer
@SpringBootApplication
public class Application{
...
}
自定义配置
默认设置下,该服务注册中心也会将自己作为客户端来尝试注册它自己,要自定义它的行为,可在appication.properties中增加如下配置
-
单节点
# appication.properties server.port =1111 eureka.instance.hostname=localhost # 单节点下面两个配置,让服务注册中心不注册自己 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false eureka.client.serviceUrl.defaultZone=http://${host}:{port}/eureka/
-
高可用设置: 原理就是注册中心互相注册
# peer1节点配置,appication.properties server.port =1111 eureka.instance.hostname=peer1 # 如果不想使用主机名来定义注册中心的地址,也可以使用IP地址的形式,需要设置eureka.instance.prefer-ip-address=true(默认false) eureka.client.serviceUrl.defaultZone=http://peer2:2222/eureka/
# peer2节点配置,appication.properties server.port =2222 eureka.instance.hostname=peer2 eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/
# /etc/hosts文件 127.0.0.1 peer1 127.0.0.1 peer2
服务提供方,需要如下配置到注册中心集群
# 服务提供方,appication.properties spring.application.name = hello-service eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer2:2222/eureka/
启动
启动后访问 http://localhost:1111/ 即可打开控制台
注册服务提供者
增加依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<!--不是spring-cloud-starter-eureka-server-->
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.3.7.RELEASE</version>
</dependency>
</dependencies>
标注@EnableDiscoveryClient
@EnableEurekaClient
@SpringBootApplication
public class Application{
...
}
指定注册中心地址
# appication.properties
spring.application.name=client-1-service
# 这里指定的是注册中心的地址
eureka.client.serviceUrl.defaultZone=http://${host}:{port}/eureka
启动
启动后,注册中心控制台便会发现该客户端
服务发现与消费
服务发现的任务由Eureka完成,而服务消费的任务由Ribbon完成。Ribbon在Eureka服务发现的基础上,实现了一套对服务实例的选择策略,从而实现对服务的消费
引入Ribbon依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
增加@LoadBalanced实现客户端负载均衡
@EnableEurekaClient
@SpringBootApplication
public class Application{
@Bean
@LoadBalanced
// 这里为啥用restTemplate,暂时不知,见后文
RestTemplate restTemplate(){
return new RestTemplate();
}
....
}
网友评论