SpringCloud
代码见:https://github.com/upupfeng/springcloud
微服务:
独立工程之间,通过框架形成的一个集群的服务调用; 将不同功能就绪切分成更小的服务
需要一种技术来整合集群,来进行管理和维护
SpringCloud微服务框架
- 服务治理 eureka :所有工程都可以在erueka中注册自己的服务名称
- 负载均衡调用组件 ribbon 前端的客户端组件
- 接口客户端组件 feign
- 熔断器: Hystrix 异常时,问题的解决
- 分布式配置: config 分布式配置组件 读取github上的配置文件,实现共享配置
- 网关组件: zuul 实现网关路由,监听
搭建一个服务注册中心Eureka_server
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>![在这里插入图片描述](https://img-blog.csdnimg.cn/20181119191940641.png)
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MSEGTUJS-1595237467947)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1541922618768.png)]
server.port=8090
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
eureka.client.serviceUrl.defaultZone=http://localhost:8090/eureka/
@SpringBootApplication
@EnableEurekaServer
public class StarterEurekaServer {
public static void main(String[] args) {
SpringApplication.run(StarterEurekaServer.class, args);
}
}
搭建Eureka客户端Eureka_client
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
server.port=8091
server.context-path=/
spring.application.name=service-hi
eureka.client.serviceUrl.defaultZone=http://localhost:8090/eureka/
@SpringBootApplication
@EnableEurekaClient
public class StartrerEurekaClient01 {
public static void main(String[] args) {
SpringApplication.run(StartrerEurekaClient01.class, args);
}
}
@RestController
public class HiController {
@Value("${server.port}")
private String port;
@RequestMapping("hi")
public String hi(){
return "hi"+port;
}
}
Ribbon+restTemplate
实现通过服务调用,完成负载均衡的访问
服务调用的客户端Ribbon
实现负载均衡的访问
代码实现Ribbon
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--Eureka相关依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!--Ribbon相关依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<!--注意这个位置,必须是springboot支持的版本。否则会报出依赖会有错误,但是编译没有问题 运行出 java.net.UnknownHostException:
的错 -->
<version>Dalston.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
eureka.client.serviceUrl.defaultZone=http://localhost:8090/eureka/
server.port=8094
spring.application.name=service-ribbon
@SpringBootApplication
@EnableDiscoveryClient
public class StarterRibbon {
public static void main(String[] args) {
SpringApplication.run(StarterRibbon.class, args);
}
@LoadBalanced //实现服务负载均衡的逻辑
@Bean
public RestTemplate getResource(){
return new RestTemplate();
}
}
@RestController
public class HiController {
@Autowired
private HiService hiService;
@RequestMapping("hi/{name}")
public String hi (@PathVariable String name){
return hiService.hi(name);
}
}
@Service
public class HiService {
@Autowired
private RestTemplate template;
public String hi(String name) {
String response = template.getForObject("http://service-hi/hi", String.class);
return name+","+response;
}
}
getForObject远程获取
String entity = template.getForEntity("http://service-hi/hi", String.class).getBody()通过getEntity获取
携带参数的话使用map传递参数
Map<String,String> map = new HashMap<>();
map.put("name", "1");
template.getForObject("http://service-hi/hi", String.class, map);
Feign
负载均衡调用服务的客户端组件 , 和ribbon相似,声明式(注解)客户端 ,使得调用更加的简单, 底层基于ribbon和restTemplate
搭建一个Feign
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<!--注意这个位置,必须是springboot支持的版本。否则会报出依赖会有错误,但是编译没有问题
运行出 java.net.UnknownHostException: 的错-->
<version>Dalston.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
eureka.client.serviceUrl.defaultZone=http://localhost:8090/eureka/
server.port=8095
spring.application.name=service-feign
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class StarterFeign {
public static void main(String[] args) {
SpringApplication.run(StarterFeign.class, args);
}
}
@RestController
public class HiController {
@Autowired
private HiService hiService;
@RequestMapping("hi")
public String sayHi(String name ){
return name+","+hiService.hi(name);
}
}
//当前接口任何方法都访问这个服务
@FeignClient("service-hi")
public interface HiService {
//这里的请求指的是被请求方的名字
@RequestMapping(value="hi1",method=RequestMethod.GET)
public String hi(@RequestParam("name") String name) ;
}
feigh如果要传参的话,使用@RequestParam(value=‘name’) String name
Feigh调用后台的服务, 某个工程宕机,不会影响调用逻辑 , Feign天生整合了Hystrix熔断机制
Hystrix
熔断器 , 容错管理工具, 集群中出现异常,可以利用熔断机制完成各种方法的封装, 实现错误的逻辑管理
搭建一个Ribbon+Hystrix的工程
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--Eureka相关依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!--Ribbon相关依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<!--注意这个位置,必须是springboot支持的版本。否则会报出依赖会有错误,但是编译没有问题 运行出 java.net.UnknownHostException:
的错 -->
<version>Dalston.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
eureka.client.serviceUrl.defaultZone=http://localhost:8090/eureka/
server.port=8096
spring.application.name=service-ribbon-hystrix
@SpringBootApplication
@EnableDiscoveryClient //发现节点
@EnableHystrix
public class StarterRHClient {
public static void main(String[] args) {
SpringApplication.run(StarterRHClient.class, args);
}
@Bean
@LoadBalanced//实现调用服务负载均衡的逻辑
public RestTemplate getResource(){
return new RestTemplate();
}
}
@Controller
public class HiController {
@Autowired
private HiService hiService;
@ResponseBody
@RequestMapping("hi")
public String sayHi(String name){
//访问一个hi的逻辑,但是ribbon并不能独立完成hi的逻辑 需要其他后台服务的支持
String response = hiService.sayHi(name);
return "RIBBON+HYSTRIX"+response;
//RIBBON:name/hello
}
}
@Service
public class HiService {
@Autowired
private RestTemplate template;
@HystrixCommand(fallbackMethod="errorHi")
public String sayHi(String name) {
String response = template.getForObject("http://service-hi/hi", String.class);
response=name+"/"+response;
return response;
}
public String errorHi(String name){
return "sorry,"+name+",~~~~~~";
}
}
Config
分布式的配置中心
github
haha-test.properties 相关配置
svn资源管理器
git 版本管理
搭建配置中心Config
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
spring.application.name=config-server
server.port=8097
spring.cloud.config.server.git.uri=https://github.com/upupfeng/study
spring.cloud.config.server.git.searchPaths=/config
spring.cloud.config.label=master
@SpringBootApplication
@EnableConfigServer
public class StarterConfigServer {
public static void main(String[] args) {
SpringApplication.run(StarterConfigServer.class, args);
}
}
事先在github上准备好对应的文件
测试配置的客户工程
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
spring.application.name=info
spring.cloud.config.profile=config
spring.cloud.config.label=master
spring.cloud.config.uri=http://localhost:8098
server.port=8099
@SpringBootApplication
public class StarterConfigClient {
public static void main(String[] args) {
SpringApplication.run(StarterConfigClient.class, args);
}
}
@Controller
public class ConfigController {
@Value("${spring.redis.nodes}")
private String nodes;
@RequestMapping("config")
@ResponseBody
public String getConfig(){
return nodes;
}
}
zuul
微服务集群提供的网关, 监听等功能的微服务组件
访问的时候根据url路径, 网关拦截的信息,访问指向的服务
搭建zuul的客户端
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
eureka.client.serviceUrl.defaultZone=http://localhost:8090/eureka/
server.port=8100
spring.application.name=service-zuul
eureka.instance.prefer-ip-address=true
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=SERVICE-RIBBON
zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.serviceId=SERVICE-FEIGN
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class StarterZuul {
public static void main(String[] args) {
SpringApplication.run(StarterZuul.class, args);
}
}