简介:微服务是最近的一两年的时间里是很火的一个概念。感觉不学习一下都快跟不上时代的步伐了,下边做一下简单的总结和介绍。
何为微服务?简而言之,微服务架构风格这种开发方法,是以开发一组小型服务的方式来开发一个独立的应用系统的。其中每个小型服务都运行在自己的进程中,并经常采用HTTP资源API这样轻量的机制来相互通信。这些服务围绕业务功能进行构建,并能通过全自动的部署机制来进行独立部署。这些微服务可以使用不同的语言来编写,并且可以使用不同的数据存储技术。对这些微服务我们仅做最低限度的集中管理。
一个微服务一般完成某个特定的功能,比如下单管理、客户管理等等。每一个微服务都是微型六角形应用,都有自己的业务逻辑和适配器。一些微服务还会发布API给其它微服务和应用客户端使用。其它微服务完成一个Web UI,运行时,每一个实例可能是一个云VM或者是Docker容器,服务与服务之间相互隔离,独立部署,相互调用,使用HTTP协议json格式进行传输和调用。
在介绍Spring Cloud 全家桶之前,首先要介绍一下Netflix ,Netflix 是一个很伟大的公司,在Spring Cloud项目中占着重要的作用,Netflix 公司提供了包括Eureka、Hystrix、Zuul、Archaius等在内的很多组件,在微服务架构中至关重要,Spring在Netflix 的基础上,封装了一系列的组件,命名为:Spring Cloud Eureka、Spring Cloud Hystrix、Spring Cloud Zuul等,下边对各个组件进行分别得介绍
我们使用微服务,微服务的本质还是各种API接口的调用,那么我们怎么产生这些接口、产生了这些接口之后如何进行调用那?如何进行管理哪?
答案:就是Spring Cloud Eureka,我们可以将自己定义的API 接口注册到Spring Cloud Eureka上,Eureka负责服务的注册于发现,如果学习过Zookeeper的话,就可以很好的理解,Eureka的角色和 Zookeeper的角色差不多,都是服务的注册和发现,构成Eureka体系的包括:服务注册中心、服务提供者、服务消费者。
pom依赖
// eureka
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
@注解
@EnableEurekaServer //服务端注解
EnableEurekaClient //客户端注解
简介:Spring为了简化客户端的Http访问的核心类。它简化了与Http服务端的通信,并且遵循了RESTful的原则。处理了HTTP的连接,使得应用简单的运用提供的URLs(提供的模版参数)运行得到结果。RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
简介:在SpringCloud中Ribbon负载均衡客户端,会从eureka注册中心服务器端上获取服务注册信息列表,缓存到本地。让后在本地实现轮训负载均衡策略Round Robin策略。
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netfilx Ribbon实现。通过Spring Cloud封装,可以轻松地将面向服务的Rest模版请求自动转换为客户端负载均衡的服务调用。
Spring cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心,配置中心,api网关那样需要独立部署,但是它几乎存在于每一个Spring cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括Feign也是基于Ribbon实现的工具。
服务器端负载均衡Nginx.
#nginx是客户端所有请求统一交给nginx,由nginx进行实现负载均衡请求转发,属于服务器端负载均衡。既请求有nginx服务器端进行转发。
客户端负载均衡Ribbon
# Ribbon是从eureka注册中心服务器端上获取服务注册信息列表,缓存到本地,让后在本地实现轮训负载均衡策略。既在客户端实现负载均衡。
应用场景的区别
# Nginx适合于服务器端实现负载均衡 比如Tomcat jboss,Ribbon适合与在微服务中RPC远程调用实现本地服务负载均衡,比如Dubbo、SpringCloud中都是采用本地负载均衡。
简介:SpringCloudFeign是将两者做了更高层次的封装以简化开发。它基于Netfix Feign实现,整合了SpringCloudRibbon和SpringCloudHystrix,除了提供这两者的强大功能外,还提供了一种声明是的Web服务客户端定义的方式。SpringCloudFeign在NetFixFeign的基础上扩展了对SpringMVC注解的支持,在其实现下,我们只需创建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定。简化了SpringCloudRibbon自行封装服务调用客户端的开发量。
@注解
@EnableFeignClients //注解开启SpringCloudFeign的支持功能
@FeignClient(name=指定服务名,fallback=指定降级类) //接口声明调用
pom依赖
// feign
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
1秒钟
将会返回异常 可以进行时间加大配置配置Feign客户端超时时间
###设置feign客户端超时时间
ribbon:
###指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间。
ReadTimeout: 5000
###指的是建立连接后从服务器读取到可用资源所用的时间。
ConnectTimeout: 5000
简介:Hystrix是国外知名的视频网站Netflix所开源的非常流行的高可用架构框架。Hystrix能够完美的解决分布式系统架构中打造高可用服务面临的一系列技术难题。
Hystrix “豪猪”,具有自我保护的能力。hystrix 通过如下机制来解决服务雪崩
效应问题。
在微服务架构中,我们把每个业务都拆成了单个服务模块,然后当有业务需求时,服务间可互相调用,但是,由于网络原因或者其他一些因素,有可能出现服务不可用的情况,当某个服务出现问题时,其他服务如果继续调用这个服务,就有可能出现线程阻塞,但如果同时有大量的请求,就会造成线程资源被用完,这样就可能会导致服务瘫痪,由于服务间会相互调用,很容易造成蝴蝶效应
导致整个系统宕掉。因此,就有人提出来断路器来解决这一问题。
单个服务出现问题
,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪
。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应
。服务间的调用超时服务间的调用失败要解决这些棘手的分布式系统可用性问题,就涉及到了高可用分布式系统中的很多重要的技术。
高并发的情况
下(默认访问数量为10个请求),如果请求达到一定极限(可以自己设置阔值
)如果流量超出
了设置阈值,然后直接拒绝访问,保护当前服务
。使用服务降级方式返回一个友好提示,服务熔断和服务降级一起使用。@注解
@EnableHystrix //开启服务保护
pom依赖
// hystrix
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
配置文件
# 熔断器启用(默认关闭)
feign.hystrix.enabled=true
hystrix.command.default.execution.timeout.enabled=true
# 超时时间(默认1000ms,单位:ms)
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000
# 线程池核心线程数(请求数10)
hystrix.threadpool.default.coreSize
#断路器默认20个
#断路器详细设置
#当在配置时间窗口内达到此数量的失败后,进行短路。默认20个)
#hystrix.command.default.circuitBreaker.requestVolumeThreshold=20
#短路多久以后开始尝试是否恢复,默认5s
#hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=5
#出错百分比阈值,当达到此阈值后,开始短路。默认50%
#hystrix.command.default.circuitBreaker.errorThresholdPercentage=50%
服务降级两种实现
// hystrix
1.方法注解 @HystrixCommand //默认已开启线程隔离、服务降级、 服务熔断默认10个请求)
2.接口方式 @FeignClient(fallback = xxxxx.class) //一般使用接口
仪表盘监控链接
简介:当一个系统中的配置文件发生改变的时候,我们需要重新启动该服务,才能使得新的配置文件生效,spring cloud config可以实现微服务中的所有系统的配置文件的统一管理,而且还可以实现当配置文件发生变化的时候,系统会自动更新获取新的配置
。
在分布式系统中,每一个功能模块都能拆分成一个独立的服务,一次请求的完成,可能会调用很多个服务协调来完成,为了方便服务配置文件统一管理,更易于部署、维护,所以就需要分布式配置中心组件了,在spring cloud中,有分布式配置中心组件spring cloud config,它支持配置文件放在在配置服务的内存中(本地),也支持放在远程Git仓库
里。引入spring cloud config后,我们的外部配置文件就可以集中放置在一个git仓库里,再新建一个config server,用来管理所有的配置文件,维护的时候需要更改配置时,只需要在本地更改后,推送到远程仓库,所有的服务实例都可以通过config server来获取配置文件,分两个角色,一是config server,二是config client。
config 服务端依赖
// config
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
config 服务端注解@
// config
@EnableConfigServer //启动config配置中心
Git环境搭建
使用码云环境搭建git服务器端
百度搜索:码云 https://gitee.com/
yml配置文件
// config
###服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
spring:
application:
####注册中心应用名称
name: config-server
cloud:
config:
server:
git:
###git环境地址
uri: https://gitee.com/xxxx/config.git
####搜索目录
search-paths:
- config
####读取分支
label: master
####端口号
server:
port: 8888
服务端启动类
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
config 客户端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
建立bootstrap.yml
// config
pring:
application:
####注册中心应用名称
name: config-client
cloud:
config:
####读取后缀
profile: dev
####读取config-server注册地址
discovery:
service-id: config-server
enabled: true
##### eureka服务注册地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
server:
port: 8882
config客户端读取配置文件
@RestController
public class IndexController {
@Value("${name}")
private String name;
@RequestMapping("/name")
private String name() {
return name;
}
}
动态刷新数据
在SpringCloud中有手动刷新配置文件和实时刷新配置文件两种方式。
1.手动方式采用actuator端点刷新数据
2.使用bus消息总线刷新
actuator 使用端点刷新
//端点发送post请求刷新
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
actuator 控制层
//端点发送post请求刷新,生效前提 在需要刷新的Bean上添加@RefreshScope注解。
@RestController
@RefreshScope
public class ConfigClientController {
// http://127.0.0.1:8882/actuator/refresh 发送post请求
//就可以使用/refresh 这个节点来刷新带有@RefreshScope注解服务的bean
@Value("${userName}")
private String userName;
}
Bootstrap.xml 新增 (开启监控断点)
#监控所有
management:
endpoints:
web:
exposure:
include: "*"
使用工具发送POST请求 http://127.0.0.1:8882/actuator/refresh 启动刷新器 从cofnig server读取最新配置
bus消息总线刷新集合RabbitMQ完成
三个项目中都加上该依赖信息
<!--核心jar包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<!-- actuator监控中心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置文件
###开启bus刷新
management:
endpoints:
web:
exposure:
include: bus-refresh
#下面配置默认连接本地可以忽略
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=用户名
spring.rabbitmq.password=密码
刷新接口 http://127.0.0.1:8882/actuator/bus-refresh
简介:网关的作用,可以实现负载均衡、路由转发、日志、权限控制、监控等。
API网关是一个更为智能的应用服务器,它的定义类似于面向对象设计模式中的Facade模式,它的存在就像是整个微服务架构系统的门面一样,所有的外部客户端访问都需要经过它来进行调度和过滤。它除了要实现请求路由、 负载均衡、 校验过滤
等功能之外,还需要更多能力,比如与服务治理框架的结合、请求转发时的熔断机制、服务的聚合等一系列高级功能。
在SpringCloud中了提供了基于NetflixZuul实现的API网关组件Spring Cloud Zuul。那么,它是如何解决上面这两个普遍问题的呢?
首先,对于路由规则与服务实例的维护间题。SpringCloud Zuul通过与SpringCloud Eureka进行整合,将自身注册为Eureka服务治理下的应用,同时从Eureka中获得了所有其他微服务的实例信息。这样的设计非常巧妙地将服务治理体系中维护的实例信息利用起来,使得将维护服务实例的工作交给了服务治理框架自动完成,不再需要人工介入。
其次,对千类似签名校验、登录校验在微服务架构中的冗余问题。SpringCloud Zuul提供了一套过滤器机制
,它可以 很好地支持这样的任务。开发者可以通过使用Zuul来创建各种校验过滤器,然后指定哪些规则的请求需要执行校验逻辑,只有通过校验的才会被路由到具体的微服务接口,不然就返回错误提示。通过这样的改造,各个业务层的微服务应用就不再需要非业务性质的校验逻辑了,这使得我们的微服务应用可以更专注千业务逻辑的开发,同时微服务的自动化测试也变得更容易实现。
简单来说,就是既具备路由转发功能,又具备过滤器功能
,比如将/aaa/**路径请求转发到service-ribbon服务上,将/bbb/***路径请求转发到service-feign服务上,比如过滤,对请求参数的信息进行过滤,不符合的进行过滤拦截等
。
pom依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
application.yml依赖
###注册 中心
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8100/eureka/
server:
port: 80
###网关名称
spring:
application:
name: service-zuul
### 配置网关反向代理
zuul:
routes:
api-a:
### 以 /api-member/访问转发到会员服务
path: /api-member/**
serviceId: app-itmayiedu-member
api-b:
### 以 /api-order/访问转发到订单服务
path: /api-order/**
serviceId: app-itmayiedu-order
Zuul 默认开启了 Ribbon本地负载均衡功能。
简介:对API文档进行更新的时候,需要通知前端开发人员,导致文档更新交流不及时;
API接口返回信息不明确
大公司中肯定会有专门文档服务器对接口文档进行更新。
缺乏在线接口测试,通常需要使用相应的API测试工具,比如postman、SoapUI等
接口文档太多,不便于管理
为了解决传统API接口文档维护的问题,为了方便进行测试后台Restful接口并实现动态的更新,因而引入Swagger接口工具。
Swagger具有以下优点
1.功能丰富:支持多种注解,自动生成接口文档界面,支持在界面测试API接口功能;
2.及时更新:开发过程中花一点写注释的时间,就可以及时的更新API文档,省心省力;
3.整合简单:通过添加pom依赖和简单配置,内嵌于应用中就可同时发布API接口文档界面,不需要部署独立服务。
pom依赖
<!-- swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
SwaggerConfig
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
// api扫包
.apis(RequestHandlerSelectors.basePackage("com.xxxx.api")).paths(PathSelectors.any()).build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title(" 微服务系统").description("Java分布式&微服务培训")
.termsOfServiceUrl("http://www.xxxx.com")
// .contact(contact)
.version("1.0").build();
}
}
启动类
controller类
访问地址:http://localhost:8060/swagger-ui.html#/swagger-controller
Zull整合Swagger管理微服务所有API
会员和订单引入Maven依赖
<!-- swagger-spring-boot -->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.7.0.RELEASE</version>
</dependency>
application.yml配置
#Api接口扫描范围
swagger:
base-package: com.ai.api
项目启动引入开启生成文档
@EnableSwagger2Doc
ZuulGateway网关
#Api接口扫描范围
swagger:
base-package: com.ai.api
项目启动引入开启生成文档
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
@EnableSwagger2Doc
public class AppGateWay {
// @EnableZuulProxy 开启网关代理
public static void main(String[] args) {
SpringApplication.run(AppGateWay.class, args);
}
// zuul配置能够使用config实现实时更新
@RefreshScope
@ConfigurationProperties("zuul")
public ZuulProperties zuulProperties() {
return new ZuulProperties();
}
// 添加文档来源
@Component
@Primary
class DocumentationConfig implements SwaggerResourcesProvider {
@Override
public List<SwaggerResource> get() {
List resources = new ArrayList<>();
// app-itmayiedu-order
resources.add(swaggerResource("app-ai-member", "/api-member/v2/api-docs", "2.0"));
resources.add(swaggerResource("app-ai-order", "/api-order/v2/api-docs", "2.0"));
return resources;
}
private SwaggerResource swaggerResource(String name, String location, String version) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion(version);
return swaggerResource;
}
}
}
Maven依赖信息
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.7.0.RELEASE</version>
</dependency>
为什么放弃Dubbo 使用SpringCloud?
相同点:SpringCloud 和Dubbo可以实现RPC远程调用框架,可以实现服务治理。
不同点:
SpringCloud是一套目前比较网站微服务框架了,整合了分布式常用解决方案遇到了问题注册中心Eureka、负载均衡器Ribbon ,客户端调用工具Rest和Feign,分布式配置中心Config,服务保护Hystrix,网关Zuul Gateway ,服务链路Zipkin,消息总线Bus等。
从架构上分析
Dubbo内部实现功能没有SpringCloud强大,只是实现服务治理,缺少分布式配置中心、网关、链路、总线等,如果需要用到这些组件,需要整合其他框架。
从更新迭代速度分析
Dubbo目前更新速度没有SpringCloud快,到SpringCloud2.0后SpringCloud会越来完善和稳定。
从开发背景角度分析
Dubbo的开发背景是阿里巴巴, 在中国也推出了非常多的优秀的开源框架
但是在SpringCloud的背景是Spring家族,Spring是专注于企业级开源框架开发,在中国,或者在整个世界上Spring框架都应用的非常广泛。所有相对来说SpringCloud的背景比Dubbo更加强大。
最后总结下:如果学习Dubbo的话,学习其他的分布式解决方案需要自己组装,反而如果学习SpringCloud,它已经把整个常用分布式解决都整合好了。
SpringCloud与Dubbo区别
相同点:都是rpc远程调用框架,可以实现服务治理(管理服务关系注册中心)
不同点:springcloud是目前比就完善的微服务框架,整合了netflix,集成了注册中心Eureka,负载均衡ribbon,客户端调用工具feign,分布式配置中心cofig,服务保护Hystrix,网关zuul gateway,服务链路zipkin,消息总线bus,
架构方面:
dubbo只有实现了服务治理,负载均衡,其他组件需要自己集成第三方应用,而springcloud已经帮忙集成所有组件,所以使用整合更加完善。
更新迭代方面
Dubbo更新缓慢,前几年基本无更新,springcloud更新维护快,更加完善稳定。
开发背景分析
dubbo是阿里开发,在国内是比较认可的,但是springcloud是spring家族开发的,国际化使用,专门专注开源框架开发,在全球使用更加广泛。
总结
Dubbo如果开发许多组件没有集成不完善,需要主动集成第三方组件,springcloud已经帮我们集成,只需要引入依赖和注解就搞定了,简单,稳定,快捷。
以上总结全部是个人和网上经验总结,如有雷同,请谅解,欢迎大家研讨技术,点关注,后续继续更新…