spring cloud总结

一.微服务概念
    什么是微服务:将一个完整的应用(单体应用)按照一定的拆分规则拆分成多个不同的服务,每个服务都能独立地进行开发、
部署、扩展。服务于服务之间通过注入RESTfulapi或其他方式调用。
    SpringCloud是在SpringBoot的基础上构建的,用于简化分布式系统构建的工具集,为开发人员提供快速建立分布式系统中的
一些常见的模式。
    例如:配置管理(configurationmanagement),服务发现(servicediscovery)
,断路器(circuitbreakers),智能路由(intelligentrouting),微代理(micro-proxy),
控制总线(controlbus),一次性令牌(one-timetokens),全局锁(globallocks),
领导选举(leadershipelection),分布式会话(distributedsessions),集群状态(clusterstate)
    SpringCloud包含了多个子项目:例如:SpringCloud Config、SpringCloud Netflix等。
二微服务概述
**微服务架构图:

spring cloud总结
二.一微服务架构的优缺点
优点:
    1.易于开发和维护:一个微服务只会关注一个特定的业务功能,所以它业务清晰、代码量较少。开发和维护单个微服务相对简单。
而整个应用是由若干个微服务构建而成的,所以整个应用也会被维持在一个可控状态。
    2.单个微服务启动较快:单个微服务代码量较少,所以启动会比较快。
    3.局部修改容易部署:一般来说,对某个微服务进行修改,只需要重新部署这个服务即可。
    4.技术栈不受限:在微服务架构中,可以结合项目业务及团队的特点,合理地选择技术栈。
    5.按需伸缩:可根据需求,实现细粒度的扩展。例如,系统中的某个微服务遇到了瓶颈,可以结合这个微服务的业务特点,增加内存
、升级CPU或者是增加节点。
缺点:
    1.运维要求较高:更多的服务意味着更多的运维投人。在微服务中,需要保证几十甚至几百个服务的正常运行与协作,这给运维带来
了很大的挑战。
    2.分布式固有的复杂性:使用微服务构建的是分布式系统。对于一个分布式系统,系统容错、网络延迟分布式事务等都会带来巨大的
挑战
    3.接口调整成本高:微服务之间通过接口进行通信。如果修改某一个微服务接口,可能所有使用了该接口的微服务都需要做调整。
    4.重复劳动:很多服务可能都会使用到相同的功能,而这个功能并没有达到分解为一个微服务的程度,这个时候,可能各个服务都会
    开发这一功能,从而导致代码重复。尽管可以使用共享库来解决这个问题(例如可以将这个功能封装成公共组件,需要该功能的微服务
    引用该组件),但共享库在多语言环境下就不一定行得通了。
二.二 微服务设计原则
    1.单一职责原则:单一职责原则指的是一个单元(类、方法或者服务等)只应关注整个系统功能中单独、有界限的一部分。
    2.服务自治原则:服务自治是指每个微服务应具备独立的业务能力、依赖与运行环境。
    3.轻量级通信机制:微服务之间应该通过轻量级的通信机制进行交互。笔者认为,轻量级的通信机制应具备两点:首先是它的体量较轻,
其次是它应该是跨语言、跨平台的。例如我们所熟悉的REST协议,就是一个典型的“轻量级通信机制";
    4.微服务粒度:微服务的粒度是难点,也常常是争论的焦点。应当使用合理的粒度划分微服务,而不是一味地把服务做小。在微服务的设
计阶段,就应确定其边界。微服务之间应相对独立并保持松耦合。
二.三 spring cloud 特点
    1.约定优于配置。
    2.适用于各种环境。开发、部署在PCServer或各种云环境(例如阿里云、AWS等)均可。
    3.隐藏了组件的复杂性,并提供声明式、无xml的配置方式。
    4.开箱即用,快速启动。
    5.轻量级的组件。spring Cloud整合的组件大多比较轻量。例如Eureka、zuul,等等,都是各自领域轻量级的实现。
    6.组件丰富,功能齐全。spring Cloud为微服务架构提供了非常完整的支持。例如,配置管理、服务发现、断路器、微服务网关等。 
    7.选型中立、丰富。例如,spring Cloud支持使用Eureka、Zookeeper或consul实现服务发现。
    8.灵活。spring Cloud的组成部分是解耦的,开发人员可按需灵活挑选技术选型。
三.组件介绍
三.一.一关于服务发现
    SpringCloud提供了多种服务发现的实现方式,例如:Eureka、Consul、Zookeeper。SpringCloud支持得最好的是Eureka,其次
是Consul,最次是Zookeeper。
    这里介绍eureka
    架构图:

spring cloud总结
    由图可知,Eureka包含两个组件:Eureka server和Eureka Client,它们的作用如下。
    * Eureka server提供服务发现的能力,各个微服务启动时,会向Eureka server注册自己的信息(例如IP、端口、微服务名称等),
Eureka server会存储这些信息。
    * Eureka Client是一个Java客户端,用于简化与Eureka server的交互。
    * 微服务启动后,会周期性(默认30秒)地向Eureka server发送心跳以续约自己的 “租期''。
    * 如果Eureka server在一定时间内没有接收到某个微服务实例的心跳,Eureka server 将会注销该实例(默认90秒)。
    * 默认情况下,Eureka server同时也是Eureka Client多个Eureka server实例,互相之间通过复制的方式,来实现服务注册表中
    数据的同步。
    * Eureka Client会缓存服务注册表中的信息。这种方式有一定的优势一一一首先,微服务无须每次请求都查询Eureka server,
从而降低了Eureka server的压力;其次,即使 Eureka server所有节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者
并完成调用。
三.一.二编写eureka server
    创建工程;microservice-diacover-user eureka:
    1.引入依赖:
    <dependencies>
        <dependency>
        <groupld>orgrspringframework.cloud</groupld>
        <artifactld>spring-cloud-starter-eureka-server</artifactld>
        </dependency>
    </dependencies>
    2.编写启动类:
    @SpringB00tApplication 
    @EnableEurekaServer 
    public class EurekaAppIication {
        public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
    3.在配置文件application.yml中添加以下内容:
    Server:    
        port: 8761 
    eureka:
        client:
            registerWithEureka: false
            fetchRegistry : false 
            serviceUrl defaultZone: http://localhost : 8761
    说明:
    registerWithEureka:表示是否将自己注册到 eureka server默认false
    fetchRegistry: 表示是否从eureka server获取注册信息
    serviceUrl defaultZoneeureka: 与eureka server交互的地址,查询和和注册都依赖这个地址,多个地址用逗号分隔
三.一.三将服务注册到server
    创建项目:microservice-provider-user
    1.引入依赖:
    <dependency>    
        <groupld>orgrspringframework.cloud</groupld>
        <artifactld>spring-cloud-starter-eureka</artifactld>
    </dependency>
    2.编写启动类:
    @EnableDiscoveryClient
    @SpringBootApplication 
    public class ProviderUserApplication { 
        public static void main(String[] args) {
        //微服务注册与发现
        SpringApplication.run(ProviderUserAppIicationacIass, args);
    }
    说明:
    也可以使用@EnableEurekaCIient注解替代@EnableDiscoveryCIient在SpringCloud中,服务发现组件有多种选择,
例如Zookeeper、consul等。@Enab1eDiscoveryC1ient为各种服务组件提供了支持,该注解是spring-cloud-commons项目的注解,
是一个高度的抽象;而@EnableEurekaCIient表明是Eureka的Client,该注解是spring-cloud-netflix 项目中的注解,只能与Eureka
一起工作。当Eureka在项目的classpath中时,两个注解没有区别。
    3.添加配置:
    spring:
        application:
            name: microservice-provider-user 
    eureka:
        client : 
            serviceUrl :
                defaultZone: http://localhost:8761/eureka/ 
            instance:
            prefer-ip-address : true
    spring.application.name :用于指定注册到eureka server上的服务名称;
    instance.prefer-ip-address = true:表示将自己的ip注册到Eureka server,默认false。
三.一.四 实现高可用,集群配置
    1.复制server  microservice-discovery-eureka,建立server  microservice-discovery-eureka-ha
    2.配置host文件 127.0.0.1 peer1 peer2
    3.修改application.yml
    spring:
        application:
            name: microservice-discovery-eureka-ha
    --
    spring:
        #指定profile-peerl 
        profiles: peerl
    server: 
        port: 8761 
    eureka:
        instance:
            #指定当profile=peerl时, 主机名是peerl 
            hostname: peerl 
        client:
            serviceUrl:
                #将自己注册到peer2这个Eureka上面去 
                defaultZone: http://peer2:8762/eureka/
    --
    spring:
        profiles: peer2
    server : 
        port : 8762 
    eureka:
        instance:
            hostname: peer 2 
        client : 
            serviceUrl:
                defaultZone: http://peerl :8761/eureka/      
三.一.四用户认证
    1.创建项目
    2.添加依赖
    <dependency>    
        <groupld>orgrspringframework.cloud</groupld>
        <artifactld>spring-boot-starter-security</artifactld>
    </dependency>
    3.文件中application.yml添加
        security: 
            basic:
                enabled: true 
            user;
                name: user 
                password: password123
    4.eureka:
        client:
            serviceUrl:
                defaultZone: http://user:[email protected]:8761/eureka/
    多网卡环境下的ip选择
        spring:
            cloud:
                inetutils:
                忽略名字
                指定正则表达式
                指定ip
                只用本地ip
        eureka:
            instance:
                per-ip-address:true
三.一.五 健康检查
    添加配置:
    eureka:
        client:
            healthcheck:
                enabled:true
三.二.一关于负载均衡

spring cloud总结
    1.新建消费者项目
    2.引入依赖
    <dependency>springframework cloud</groupld>
        <artifactld>spring-cloud-starter-ribbon</artifactld>
    </dependency>
    spring-cloud-starter-eureka 中包含ribbon 可不再引用
    3.为类添加注解 @LoadBalanced
    @Bean 
    @LoadBalanced 
    public RestTemplate restTemplate() {
    return new Rest Template();}
    4.修改controller
    @RestController 
    public class MovieController {
        private static final Logger LOGGER = LoggerFactory. getLogger(MovieControl ler class) ; 
        @Autowired 
        private RestTemplate restTemplate; 
        @Autowired 
        private LoadBalancerClient loadBalancerClient;
        @GetMapping( 'I /user/{id} " ) 
        public User findById(@PathVariable Long id) { 
            return this.restTemplate.getFor0bject("http://microservice-provider-user/+id, User.class) ;}
        @GetMapping( " /log-instance " ) 
        public void logUserInstance() {
            Servicelnstance servicelnstance = this. loadBalancerClient.choose(" microservice-provider-user " ) ;
            MovieController.LOGGER.info("{}:{}:{}",servicelnstance.getServiceId(),
            serviceInstanceugetHost(),serviceInstance .getPort();}
三.二.二 自定义ribbon配置
    使用java代码自定义:
    使用属性自定义:
三.二.三单独使用ribbon

spring cloud总结
    1.修改配置
    server: 
        port: 8010 
    spring:
        application:
            name: microservice-consumer-movie 
    microservice-provider-user:
        ribbon:
        list0fServers:localhost:8000, localhost:8001
三.三 关于rest api调用
三.三.一feign简介
    Feign是Netflix开发的声明式、模板化的HTTP客户端。Spring Cloud对Feign进行了增强,使Feign支持了spring Mvc注解,
并整合了Ribbon和Eureka,从而让Feign的使用更加方便。
三.三.二为消费者整合feign
    1.添加依赖
    <dependency>
        <groupld>orgspringframework.cloud</groupld>
        <artifactld>spring-cloud-starter-feign</artifactld> 
    </dependency>
    2.创建feign接口
    @FeignClient(name: mlcroservice-provider-user") 
    public interface UserFeignClient {
    @RequestMapping(value - "/{id}" , method = RequestMethod. GET)
    public User findById(@PathVariable("id") Long id);}
    3.修改controller
    @RestController 
    public class MovieController {
    @Autowired 
    private UserFeignClient userFeignClient;
    @GetMapping( "/user/{id}" ) 
    public User findById(@PathVariable Long id){ 
    return this.userFeignClient.findById(id);}
    4.修改启动类
    @EnableDiscoveryClient
    @SpringBootApplication 
    @EnableFeignClients
    public class ConsumerMovieApplication{ public static void main(String[] args) {
        SpringApplication run(ConsumerMovieApplication. class , args) ;}
三.三.三自定义feign配置
    feign的默认配置类是FeignClientConfiguration,spring cloud允许通过注解FeignClient的
configuration属性自定义Feign,自定义级别比FeignClientConfiguration要高。
    1.创建feign配置类(FeignConfiguration)
    2.修改feign接口
    @FeignClient(name="项目名称",configuration=FeignConfiguration。class)
    public interface UserFeignClient{
    //使用Feign自带的注解
    @RequestLine("Get/{id}")
    public User findById(@Param("id")Long id)
    }
    说明:和ribbon配置一样,FeignConfiguration也不能包含在成效上下文的@ComponentScan中(设计是否共享)
    注:有时自定义方式满足不了需求需要手动创建Fiegn(此处不做过多说明,可参考Feign Bulider Api)
三.三.四 其他
    Feign 支持继承。
    有时可能需要对请求响应进行压缩,Feign也是支持。
    Feign日志记录:
    get请求多参数URL:1.用@requestParam("id")String id;2.requestParam Map<String,Object> msp
    post请求多参数:requestMethod.Post;
    
三.四.一 容错机制

spring cloud总结
    Hystrix简介:
    Hystrix是由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,从而提升系统的可用性
与容错性。Hystrix主要通过以下几点实现延迟和容错。
    1.包裹请求:使用Hystrixcommand(或Hystrix0bservableCommand)包裹对依赖的调用逻辑,每个命令在独立线程中执行。
这使用到了设计模式中的“命令模式"。
    2.跳闸机制:当某服务的错误率超过一定阈值时,Hystrix可以自动或者手动跳闸,停止请求该服务一段时间。
    3.资源隔离:Hystrix为每个依赖都维护了一个小型的线程池(或者信号量)。如果该线程池已满,发往该依赖的请求就被立即拒绝,
而不是排队等候,从而加速失败判定。
    4.近乎实时监控运行指标的配置编号。
    5.回退机制,熔断则执行回退逻辑。
    6.自我修复,熔断器打开一段时间,会自动进入“半开”状态。
三.四.二 通用方式整合Hystrix
    1.复制项目
    2.添加依赖
    <dependency> cloud</groupld>
        <groupld>orgspringframework.cloud</groupld>
        <artifactld>spring-cloud-starter-hystrix</artifactld>
    </dependency> 
    3.在启动类上加注解:@EnableCircuitBreaker或者EnableHystrix
    4.修改controller 在方法上添加@hystrixCommand(fallbackmethod="fallback")(回退方法自己定义);还有@HystrixProper属性可用。
三.四.三 断路器的状态监控
    <dependency>
        <groupld.org/springframeworknboot</groupld>
        <artifactld>spring-boot-starter-actuator</artifactld> 
    </dependency>
    断路器的状态也会暴露在Actuator提供的/health端点中,这样就可以直观地了解断路器的状态。
    持续快速(没达到频率)访问 http://peerl :8761/user/1  可看到"status" "CIRCUIT OPEN"。
三.四.四 使用Turbine聚合监控数据
    简介:Turbine是一个聚合Hystrix监控数据的工具,它可将所有相关/hystrix.stream端点的数据聚合到一个组合的/turbine.stream中,
从而让集群的监控更加方便。
    步骤:
    1.添加依赖:
    <dependency>
        <groupld.org/springframeworknboot</groupld>
        <artifactld>spring-boot-starter-turbine</artifactld> 
    </dependency>
    2.启动类上添加@enableturbine
    3.配置文件添加
    turbine :
        appConfig: microservice-consumer-movie,microservice-consumer-movie-feignhystrix-fallback-stream 
        clusterNameExpression: “default"
    说明:一些场景下,前文的方式无法正常工作(例如微服务与Turbine网络不通),此时,可借助消息中间件实现数据收集。各个微服务
将Hystrix Command的监控数据发送至消息中间件,Turbine消费消息中间件中的数据。    
三.四.五 其他
    线程隔离与传播上下文(有点复杂此处不提)
    feign使用Hystrix:
    1.
@FeignClient(name="microservice-provider-user fallback = FeignClientFallback a class) 
public interface UserFeignClient {
    @RequestMapping(value-"/{id}", method = RequestMethod.GET) 
    public User findById(@PathVariable("id") Long id);}
    2.
@Component 
public class FeignClientFallback implements UserFeignClient { 
    @0verride 
    public User findById(Long id) { 
    User user = new User();
    user.setId(-1L) ; 
    return user;}
    通过fallbackFactory查看回退原因;
    为Feign禁用Hystrix:在接口上加注解@FeignClient(name="",configuration=FeignDisabledHystrixConfigeration.class);
    使用Dashboard可视化监控Hystrix:
    1.导入依赖
    <dependency>
        <groupld>orgspringframework.cloud</groupld>    
        <artlfactld>spring-cloud-starter-hystrix-dashboard</artifactld>
    </dependency>
    2.启动类上添加 @EnableHystrixDashboard 
三.五 网关组件

spring cloud总结
    Zuul简介
    zuul是Netflix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用。 zuul的核心是一系列的过滤器,这些过滤器可以完成以下功能。
    。身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符的请求。
    。审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生产视图。
    。动态路由:动态地将请求路由到不同的后端集群。
    。压力测试:逐渐增加指向集群的流量,以了解性能。
    。负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求。
    。静态响应处理:在边缘位置直接建立部分响应,从而避免其转发到内部集群。
    。多区域弹性:跨越AWS Region进行请求路由,旨在实现ELB(Elastic Load Balancing)使用的多样化,以及让系统的边缘更贴近系统的使用者。
    spring Cloud对zuul进行了整合与增强。目前,zuul使用的默认HTTP客户端是Apache HTTP Client
    优点:
    1.易于监控。可在微服务网关收集监控数据并将其推送到外部系统进行分析。
    2.易于认证。可在微服务网关上进行认证,然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。
    3.减少了客户端与各个微服务之间的交互次数。
三.五.一 编写zuul
    1.引入依赖:
    <dependency>
        <groupld.org/springframework-cloud</groupld>:
        <artifactld>spring-cloud-starter-zuul</artlfactld>
    </dependency>
        <dependency>
        <groupld.org/springframework-cloud</groupld>:
        <artifactld>spring-cloud-starter-Eureka</artlfactld>
    </dependency>
    2.启动类上添加 @EnableZuulProxy
    3.添加配置:
    server: 
        port: 8040 
    spring:
        application :
            name: microservice-gateway-zuul 
    eureka:
        client :
            service-url :
                defaultZone: http://localhost:8761/eureka/
    
    注:路由的详细配置
    1.自定义指定访问路径 
    zuul:
        routes:
            microservice-provider-user: /user/**
    2.指定忽略微服务:
    zuul:
        ignored-services:服务名称 
    3.忽略所有微服务,只有指定路由
    zuul:
        ignored-services:'*'
        microservice-provider-user: /user/**
    4.同时指定path和url
    zuul:
        routes:
            user-routes: #指定路由名称可任意取名
                url:http://localhost:8761/
                path:/user/**
    5.使用正则表达式匹配路由规则
    借助PatternServiceRouteMapper类
    6.路由前缀
    Zuul:
    prefix:/api
    srrip-prefix:false
    routes:
        microservice-provider-user: /user/**
    7.忽略某些路径
    ignoredPatrerns:/adimn/*
三.五.二 敏感header
    指定敏感 加 sensitive-headers: ****
    忽略敏感 加 ignored-headers:***
三.五.三 zuul文件上传
    1.建立工程
    2.导入依赖
    <dependency>
        <groupld>org springf ramework.boot</groupld>
        <artifactld>spring-boot-starter-web</artifactld>
    </dependency>
    <dependency>
        <groupld>org springf ramework.boot</groupld>
        <artifactld>spring-cloud-starter-eureka</artifactld>
    </dependency>
    <dependency>
        <groupld>org springf ramework.boot</groupld>
        <artifactld>spring-boot-starter-actuator</artifactld> 
    </dependency>
    3.编写controller
        @RequestMapping(value="/upload",method=RequestMethod.POST) 
        public @ResponseBody String handleFileUpload(@RequestParam(value="file",required = true) MultipartFile file) 
        throws IOException {
            byte[] bytes - file.getBytes();
            File fileT0Save    new = FileCopyUtils.copy(bytes, fileToSave); 
            return fileToSave.getAbsolutePath();}}
    4.配置文件
        server: 
            port: 8050 
        eureka : 
            client:
                serviceUrl:
                    defaultZone: http://localhost:8761/eureka/ 
                instance:
                    prefer-ip-address: true 
        spring:
            application:
                name: microservice-file-upload
            http:
                multipart:
                    max-file-size: 2000Mb    # Max file Size 默认1M
                    max-request-size: 2500Mb    # Max request size 默认10M
三.五.三 其他
    1.zuul过滤器:
        过滤器是zuul的核心组件,zuul大部分功能都是通过过滤器来实现的。zuul中定义了4种标准过滤器类型:
    。PRE:这种过滤器在请求被路由之前调用。可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
    。ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。
    。POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
    。ERROR:在其他阶段发生错误时执行该过滤器。
    自定义过滤器:创建类继承抽象类ZuulFilter,重写四种方法分别返回值为,过滤器种类、过滤器执行顺序、过滤器是否执行、过滤器执行逻辑。
    禁用过滤器:spring默认为Zuul启动了一些过滤器。关闭方式:zuul.<simpleClassName>.<filteType>.disabled=true.
    2.zuul高可用
        zuul客户端也注册到了eureka server:只需要将zuul多个节点注册到eureka server.
        zuul客户端未注册到了eureka server:现实中,这种场景往往更常见,例如,zuul客户端是一个手机APP一一一不可能让所有的手机终端都注册到
Eureka server上。这种情况下,可借助一个额外的负载均衡器来实现 zuul的高可用,例如Nginx、HAProxy、F5等。
    3.zuul聚合微服务:
        外部请求需要查询zuul后端的多个微服务。举个例子,一个电影售票手机APP,在购票订单页上,既需要查询“电影微服务"获得电影相关信息,又需要查询
    “用户微服务"获得当前用户的信息。如果让手机端直接请求各个微服务(即使使用 zuul进行转发),那么网络开销、流量耗费、耗费时长可能都无法令我们
    满意。那么对于这种场景,可使用zuul聚合微服务请求一一一手机APP只需发送一个请求给zuul,由 zuul请求用户微服务以及电影微服务,并组织好数据给手机APP。
三.六 spring cloud 集中配置

spring cloud总结
    config server是一个可横向扩展、集中式的配置服务器,它用于集中管理应用程序各个环境下的配置,默认使用Git存储配置内容(也可使用Subversion、
本地文件系统或vault 存储配置,限于篇幅,不做讨论),因此可以很方便地实现对配置的版本控制与内容审计。
    config Client是config server(放git)的客户端,用于操作存储在config server中的配置属性。如图所示,所有的微服务都指向config Servero各个微服务在启动时,
会请求config server以获取所需要的配置属性,然后缓存这些属性以提高性能。
三.七 服务跟踪Spring Cloud Sleuth
    Spring Cloud Sleuth有很多术语,看起来复杂,所以直接给思路上代码
    1.建立工程
    2.导入依赖
    <dependency>
        <groupld>org springf ramework.cloud</groupld>
        <artifactld>spring-cloud-starter-sleuth</artifactld> 
    </dependency>
    3.修改配置 application.yml
    spring:
        application:
            name: microservice-provider-user 
    logging:
        level:
            root: INFO 
            org.springframeworknweba servlet.DispatcherServlet: DEBUG
    由于篇幅有限,笔者无法为大家讲述微服务中的方方面面。微服务是一个非常宏观的话题,要想切实落地微服务架构,光靠看几篇博客是远远不够的。微服务粒度、
    持续集成、自动化机制、组织机构的建设乃至如何从传统架构向微服务架构迁移,都是值得我们深思的问题。
    spring cloud 系列还有一些更细化的东西太多了,手写麻烦,重点绝大多数都在这了。仅仅使用 spring cloud 完全没为题了,至于一些关联内容用到再去研究,没多大问题。
    
    附录(常见注解):@Configuration
    @EnableAsync
    @EnableCaching
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @Bean
    @Primary 一个接口有多个实现类
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "entityManagerFactoryPrimary",
            transactionManagerRef = "transactionManagerPrimary",
            basePackages = {"cn.dlj1.springboot.dao"}) //设置Repository所在位置
    @PropertySource("classpath:conf/db/db-${spring.profiles.active}.properties")
    @Scheduled(cron="0/10 * * * * ?")
    @ControllerAdvice 全局异常处理 全局数据绑定 全局数据预处理
    @EnableResourceServer
    @EnableWebSecurity
    @ExceptionHandler(value = Exception.class)