Spring Cloud 教程:https://windmt.com/2018/04/14/spring-cloud-1-services-governance/
什么是微服务
微服务英文名称:Microservice 意思是一个一体化的应用被分解为一个个的小应用,这些小的Web服务可以独立地编译及部署。它们又彼此相互协作,作为一个整体为用户提供功能,却可以独立地进行扩。
微服务的特点
解耦:同一系统内的服务大部分可以被解耦。因此应用,作为一个整体,可以轻易地被构建、修改和扩展。
组件化:微服务可以被看成相互独立的组件,这些组件可以被轻易地替换和升级。
业务能力:微服务很小,它们可以专注于某种单一的能力
自治:开发者和团队可以独立地工作,提高开发速度。
职责明确:微服务不把应用看成一个又一个的项目。相反,它们把应用当成了自己需要负责的项目。
去中心化管理:关注于使用正确的工具来完成正确的工作。这也就是说,没有标准化的方式或者技术模式。开发者们有权选择最好的工具来解决问题。
敏捷性:微服务支持敏捷开发。任何新功能都可以被快速开发或丢弃。
微服务的优点
1、易于开发和维护
2、启动较快
3、局部修改容易部署
4、技术不受限
5、按需伸缩
6、DevOps
常见的微服务框架
阿里的Dubbo, apache Consul ,Spring Cloud Eureka
Springcloud组件介绍
(1)Spring Cloud Eureka
我们使用微服务,微服务的本质还是各种API接口的调用,那么我们怎么产生这些接口、产生了这些接口之后如何进行调用那?如何进行管理哪?
答案就是Spring Cloud Eureka,我们可以将自己定义的API 接口注册到Spring Cloud Eureka上,Eureka负责服务的注册于发现,如果学习过Zookeeper的话,就可以很好的理解,Eureka的角色和 Zookeeper的角色差不多,都是服务的注册和发现,构成Eureka体系的包括:服务注册中心、服务提供者、服务消费者。
(2)Spring Cloud Ribbon
在上Spring Cloud Eureka描述了服务如何进行注册,注册到哪里,服务消费者如何获取服务生产者的服务信息,但是Eureka只是维护了服务生产者、注册中心、服务消费者三者之间的关系,真正的服务消费者调用服务生产者提供的数据是通过Spring Cloud Ribbon来实现的。
在(1)中提到了服务消费者是将服务从注册中心获取服务生产者的服务列表并维护在本地的,这种客户端发现模式的方式是服务消费者选择合适的节点进行访问服务生产者提供的数据,这种选择合适节点的过程就是Spring Cloud Ribbon完成的。
(3)Spring Cloud Feign
上述(1)、(2)中我们已经使用最简单的方式实现了服务的注册发现和服务的调用操作,如果具体的使用Ribbon调用服务的话,你就可以感受到使用Ribbon的方式还是有一些复杂,因此Spring Cloud Feign应运而生。
Spring Cloud Feign 是一个声明web服务客户端,这使得编写Web服务客户端更容易,使用Feign 创建一个接口并对它进行注解,它具有可插拔的注解支持包括Feign注解与JAX-RS注解,Feign还支持可插拔的编码器与解码器,Spring Cloud 增加了对 Spring MVC的注解,Spring Web 默认使用了HttpMessageConverters, Spring Cloud 集成 Ribbon 和 Eureka 提供的负载均衡的HTTP客户端 Feign。
简单的可以理解为:Spring Cloud Feign 的出现使得Eureka和Ribbon的使用更为简单。
(4)Spring Cloud Hystrix
我们在(1)、(2)、(3)中知道了使用Eureka进行服务的注册和发现,使用Ribbon实现服务的负载均衡调用,还知道了使用Feign可以简化我们的编码。但是,这些还不足以实现一个高可用的微服务架构。
例如:当有一个服务出现了故障,而服务的调用方不知道服务出现故障,若此时调用放的请求不断的增加,最后就会等待出现故障的依赖方 相应形成任务的积压,最终导致自身服务的瘫痪。
Spring Cloud Hystrix正是为了解决这种情况的,防止对某一故障服务持续进行访问。Hystrix的含义是:断路器,断路器本身是一种开关装置,用于我们家庭的电路保护,防止电流的过载,当线路中有电器发生短路的时候,断路器能够及时切换故障的电器,防止发生过载、发热甚至起火等严重后果。
(5)Spring Cloud Config
对于微服务还不是很多的时候,各种服务的配置管理起来还相对简单,但是当成百上千的微服务节点起来的时候,服务配置的管理变得会复杂起来。
分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件Spring Cloud Config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。在Cpring Cloud Config 组件中,分两个角色,一是Config Server,二是Config Client。
Config Server用于配置属性的存储,存储的位置可以为Git仓库、SVN仓库、本地文件等,Config Client用于服务属性的读取。
Spring Cloud Ribbon客户端负载均衡器由此而来。
(6)Spring Cloud Zuul
服务网关。
服务网关是微服务架构中一个不可或缺的部分。通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由、均衡负载功能之外,它还具备了权限控制等功能。Spring Cloud Netflix中的Zuul就担任了这样的一个角色,为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性。
Spring Cloud Eureka搭建和使用
创建父项目EurekaAndZuulParent
pom:
org.springframework.boot
spring-boot-starter-parent
1.5.2.RELEASE
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
@className:EurekaApp
@discription:
@author:zz
@crateTime:2019-01-06 23:14
*/
@SpringBootApplication
@EnableEurekaServer
#@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class EurekaApp {
public static void main(String[] args) {
SpringApplication.run(EurekaApp.class,args);
}
}
创建服务提供者(一个服务)
创建父项目ServiceParent
server.port=6667
spring.application.name=server-user
eureka.client.service-url.defaultZone=http://localhost:6666/eureka/
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
package com.aaa.client;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
创建服务提供者(另外一个服务)
同上
创建zuul接口代理—实现路由功能
server.port=6668
spring.application.name=server-zuul
eureka.client.service-url.defaultZone=http://localhost:6666/eureka/
zuul.routes.user-href.path=/module1/**
zuul.routes.user-href.serviceId=server-module1
zuul.routes.user-href1.path=/module2/**
zuul.routes.user-href1.serviceId=service-module2
package com.aaa;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class ZuulApp {
public static void main(String[] args) {
SpringApplication.run(ZuulApp.class,args);
}
}
zuul 实现类似拦截器功能
展示测试效果
编写filter类,并交给spring管理,继承com.netflix.zuul.ZuulFilter;
使用Zuul提供的获取上下文对象类(RequestContext)获取相关其他相关对象
RequestContext ctx = RequestContext.getCurrentContext();
接口方法中
filterType:过滤器的类型.
pre:可以在请求被路由之前调用
route:在路由请求时候被调用
post:在route和error过滤器之后被调用
error:处理请求时发生错误时被调用
shouldFilter:是否执行
filterOrder:优先级,越小执行级别越高
使用拦截器IP过滤功能
服务之间的相互调用
RestTemplate 介绍
简化了发起HTTP请求以及处理响应的过程,并且支持REST。
https://blog.csdn.net/itguangit/article/details/78825505
在想调用其他服务模块的启动类上加入
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
在服务层注入,并使用它调用注册服务方法
restTemplate.getForObject(“http://服务名/方法?参数”, 对象, 参数);
feign的使用,完成服务之间相互调用
1,添加依赖:
org.springframework.cloud
spring-cloud-starter-feign
2,启动类中添加:
@EnableFeignClients
3,编写接口,使用注解:
@FeignClient(value = “注册服务名”)
public interface xxx{
@RequestMapping(“服务中的方法”)
Map method();
}
4,controller 注入接口
注意: 带参服务方法的调用
hystrix 的使用
1,添加依赖:
org.springframework.cloud
spring-cloud-starter-hystrix
2,启动类中添加:
@EnableHystrix
3,服务类使用注解:
@HystrixCommand(fallbackMethod = “getPayError”)
public String getPayError(int payId){
return “error:”+payId;
}
4,测试方法
在调用方法中制造异常,看是否调用熔断方法
参考帖子:
https://springcloud.cc/
https://springcloud.cc/spring-cloud-dalston.html
https://blog.csdn.net/tzs_1041218129/article/details/78701772
https://blog.csdn.net/xlgen157387/article/details/77773908