背景
陆陆续续把老卫的从天气项目看 Spring Cloud 微服务治理给看完了,总结一下收获及遇到的问题。实战地址:实战项目地址
总结
实战项目是用gradle来进行管理的,我使用maven管理的。从start.spring.io下载模板,我用的版本跟实战项目的不一样,但是可以兼容
Spring Boot版本:2.1.4.realease
Spring Cloud版本:Greenwich.SR1
服务注册与发现
- 使用eureka server作为注册中心。配置如下:
- 添加eureka server依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
- 启动类Application加上
@EnableEurekaServer
注解
@SpringBootApplication
@EnableEurekaServer
public class MsaWeatherEurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(MsaWeatherEurekaServerApplication.class, args);
}
}
- 配置
application.properties
文件
server.port=8761
spring.application.name=msa-weather-eureka-server
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
- 使用eureka client注册到注册中心
- 添加eureka client依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 启动类Application加上
@EnableDiscoveryClient
注解
@SpringBootApplication
@EnableDiscoveryClient
public class MsaWeatherEurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(MsaWeatherEurekaClientApplication.class, args);
}
}
- 配置
application.properties
文件
spring.application.name=msa-weather-eureka-client
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
开启多个微服务实例可以将client打包成jar包,用jar -jar xxx.jar --server.port=8080
运行即可,端口可更改。
Feign声明式服务调用
feign默认集成了ribbon,默认实现了负载均衡,负载均衡实现在客户端中。
- 添加feign依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 启动类Application加上
@EnableFeignClients
注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class InitializrStartApplication {
public static void main(String[] args) {
SpringApplication.run(InitializrStartApplication.class, args);
}
}
- 配置
application.properties
文件
spring.application.name=msa-weather-report-eureka-feign
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
feign.client.config.feignName.connectTimeout=5000
feign.client.config.feignName.readTimeout=5000
- 在接口中使用
@FeignClient("服务的spring.application.name")
注解来调用服务
@FeignClient("msa-weather-city-eureka")
public interface CityClient {
@GetMapping("/cities")
List<City> listCity() throws Exception;
}
路由网关 zuul
使用zuul做微服务api的统一管理。
- 添加zuul依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
- 启动类Application加上
@EnableZuulProxy
注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class MsaWeatherEurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(MsaWeatherEurekaClientApplication.class, args);
}
}
- 配置
application.properties
文件
server.port=8090
spring.application.name=msa-weather-eureka-client-zuul
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
#测试
zuul.routes.hi.path=/hi/**
zuul.routes.hi.serviceId=msa-weather-eureka-client
#城市服务API接口
zuul.routes.city.path=/city/**
zuul.routes.city.serviceId=msa-weather-city-eureka
#数据服务API接口
zuul.routes.data.path=/data/**
zuul.routes.data.serviceId=msa-weather-data-eureka
- 在客户端调用时的案例
@FeignClient("msa-weather-eureka-client-zuul")
public interface DataClient {
@GetMapping("/city/cities")
List<City> listCity() throws Exception;
@GetMapping("/data/weather/cityId/{cityId}")
WeatherResponse getDataByCityId(@PathVariable("cityId") String cityId);
}
之前是调用城市服务@FeignClient("msa-weather-city-eureka")
中使用@GetMapping("/cities")
,现在使用zuul网关,全部统一调用网关@FeignClient("msa-weather-eureka-client-zuul")
,使用在application.properties中配置好的路径进行调用@GetMapping("/city/cities")
集中化配置 config 配置
- 配置服务器 config-server 配置
把配置集中在git服务器上管理。可以更好的管理配置文件。支持properties和yml文件。
- 添加 config-server 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
- 启动类Application加上
@EnableConfigServer
注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
public class MsaWeatherEurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(MsaWeatherEurekaClientApplication.class, args);
}
}
- 配置
application.properties
文件
server.port=8888
spring.application.name=msa-weather-eureka-config-server
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
spring.cloud.config.server.git.uri=https://gitee.com/VioletKiss/springConfigTest
spring.cloud.config.server.git.searchPaths=repo
- 注意事项
在git服务器创建仓库,并新建文件夹repo,其中application.properties文件中uri为你的仓库地址,searchPaths为你放配置文件的文件夹。
- 客户端 config-client 配置
注意:配置文件的命名规则-spring官方规则:更多信息请看官方github地址
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
- 添加 config-client 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
- 配置
application.properties
文件
spring.application.name=msa-weather-eureka-config-client
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
spring.cloud.config.profile=dev
spring.cloud.config.uri=http://localhost:8888/
- 测试配置是否生效
在git上的配置文件名为msa-weather-eureka-config-client-dev.properties
,内容如下:
auther=bao
version=1.0
编写测试代码测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MsaWeatherEurekaClientApplication.class)
public class MsaWeatherEurekaServerApplicationTests {
@Value("${auther}")
private String auther;
@Test
public void contextLoads() {
System.out.println(auther.equals("bao"));
}
}
- 注意事项
我在这里由于没看到后面的命名规则,试的差点崩溃,真是被自己蠢死了,注意正确配置application.properties中的config配置,示例中的配置取得是application.name+config.profile命名的配置文件,即msa-weather-eureka-config-client-dev.properties
或者msa-weather-eureka-config-client-dev.yml
熔断器 hystrix
熔断器作用在于在服务器负荷过大时拒绝客户端的调用并进行回应。
- 添加 hystrix 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- 启动类Application加上
@EnableCircuitBreaker
注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker
public class MsaWeatherEurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(MsaWeatherEurekaClientApplication.class, args);
}
}
- 使用方法①
在调用服务接口的地方添加@HystrixCommand(fallbackMethod = "自定义方法名")
,一旦服务负荷熔断,调用自定义方法,注意返回值要统一。
@RestController
public class CityController {
@Autowired
private CityClient cityClient;
@GetMapping("/cities")
@HystrixCommand(fallbackMethod = "defaultCities")
public String listCity() {
String body = cityClient.listCity();
return body;
}
public String defaultCities() {
return "city Data Server is down!";
}
}
- 使用方法②
在调用服务的接口上的注解@FeignClient()
添加fallback
参数,当发生熔断时调用fallback
参数指定的类的方法
@FeignClient(value = "msa-weather-eureka-client-zuul",fallback = DataClientFallback.class)
public interface DataClient {
@GetMapping("/city/cities")
List<City> listCity() throws Exception;
@GetMapping("/data/weather/cityId/{cityId}")
WeatherResponse getDataByCityId(@PathVariable("cityId") String cityId);
}
fallback调用的类需实现服务接口,并重写熔断后需要执行的方法,注意加上@Component
注解。
@Component
public class DataClientFallback implements DataClient{
@Override
public List<City> listCity() throws Exception {
List<City> cityList = new ArrayList<>();
City city = new City();
city.setCityId("101280601");
city.setCityName("深圳");
cityList.add(city);
city = new City();
city.setCityId("101280301");
city.setCityName("惠州");
cityList.add(city);
return cityList;
}
@Override
public WeatherResponse getDataByCityId(String cityId) {
return null;
}
}
自动扩展
垂直扩展:升级硬件(有瓶颈,根据硬件水平限制)
水平扩展:配置多台相同性能主机
服务需要具备自我注册和自我发现功能才能进行自动扩展
自动扩展的不同级别:
- 应用程序级别(基本采用相同的技术栈)
- 基础架构级别(占用更多的系统资源)
自动扩展的常用方法:
- 资源限制
- 特定时间段
- 消息长度
- 业务参数
- 根据预测
实现自动扩展所需的关键功能:
- 一个容器抽象层,在许多物理或虚拟机提供统一的抽象
- 容器编排和初始化系统在集群抽象智商之上智能管理部署
资源分配常用算法:
- 传播(平均分配到各个主机上)
- 装箱(先装满一台再继续装另一台)
- 随机(随机分配到各个主机上)
常用的容器编排技术:
- Docker Swarm
- Kubernetes
- Apache Mesos
结语
实战课程不难理解,是Spring Cloud的入门课程,如果要深入了解需要自己去查看各个组件的应用。
自己敲的项目源码:码云地址