Spring-Cloud-1

来源:互联网 发布:2年的java工程师的薪资 编辑:程序博客网 时间:2024/06/06 07:32

使用Spring Cloud实战微服务

微服务简介

单体架构

这里写图片描述

​ 一个归纳包(例如WAR格式)包含了应用所有功能的应用程序,我们通常称之为单体应用。架构单体应用的方法论,我们称之为传统的单体应用架构。

缺点:

1.复杂性高

​ 以一个百万行级别的单体应用为例,整个项目包含的模块非常多,模块的边界模糊,依赖关系不清晰,代码质量参差不齐,混乱的堆砌在一起……整个项目非常复杂。每次修改代码都心惊胆颤,甚至添加一个简单的功能,或者修改一个BUG都会造成隐含的缺陷。

2.技术债务

​ 随着时间推移、需求变更和人员更迭,会逐渐形成应用程序的技术债务,并且越积越多。“不坏补修 (Not broken,don’t fix)”,这在软件开发中非常常见,在单体应用中这种思想更甚。已使用的系统设计或代码难以修改,因为应用程序的其他模块可能会以意料之外的方式使用它。

3.部署频率低

​ 随着代码的增多,构建和部署的时间也会增加。而在单体应用中,每次功能的变更或缺陷的修复都会导致我们需要重新部署整个应用。全量部署的方式耗时长、影响的范围大、风险高,这使得单体应用项目上线部署的频率较低。而部署的频率低又导致两次发布之间会有大量的功能变更和缺陷修复,出错概率较高。

4.拓展能力受限

​ 单体应用只能作为一个整体进行拓展,无法结合业务模块的的特点进行伸缩。例如,应用中有的模块是计算密集型的,它需要强劲的CPU;有的模块则是IO密集型的,需要更大的内存。由于这些模块部署在一起,我们不得不在硬件的选择上做出妥协。

5.阻碍技术创建

​ 单体应用往往使用统一的技术平台或方案解决所有问题,团队的每个成员都必须使用相同的开发语言和框架,想要引入新的框架或技术平台会非常困难。例如,一个使用Struts2构建的100万行代码的单体应用,如果想要换用Spring MVC,切换成本无疑是非常高的。

架构的演进

单体架构

SOA(分布式,面向服务架构)

微服务

微服务架构

http://www.martinfowler.com/articles/microservices.html
In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.

翻译:简而言之,微服务架构风格这种开发方法,是以开发一组小型服务的方式来开发一个独立的应用系统的。其中每个小型服务都运行在自己的进程中,并经常采用HTTP资源API这样轻量的机制来相互通信。这些服务围绕业务功能进行构建,并能通过全自动的部署机制来进行独立部署。这些微服务可以使用不同的语言来编写,并且可以使用不同的数据存储技术。对这些微服务我们仅做最低限度的集中管理。

微服务特性:

1.每个微服务可独立运行在自己的进程里;

2.一系列独立的微服务共同构建起整个系统;

3.每个服务为独立的业务开发,一个微服务只关注某个特定的功能,例如订单管理、用户管理等;

4.微服务之间通过一些轻量级的通信机制进行通信,例如通过REST API进行调用;

5.可以使用不同的语言与数据存储技术;

6.全自动的部署机制。

这里写图片描述

微服务架构的优点与挑战

微服务架构的优点:

1.易于开发和维护

​ 一个微服务只关注一个特定的业务功能,所以它的业务清晰、代码量较少。开发和维护单个微服务相对是比较简单的。而整个应用是由若干个微服务构建而成的,所以整个应用也会维持在可控状态。

2.单个微服务启动较快

​ 单个微服务代码量较少,所以启动会比较快。

3.局部修改容易部署

​ 单体应用只要有修改,就得重新部署整个应用,微服务解决了这样的问题。一般来说,对某个微服务进行修改,只需要重新部署这个服务即可。

4.技术栈不受限

​ 在微服务中,我们可以结合项目业务及团队的特点,合理的选择技术栈。例如某些服务可以使用关系型数据库MySQL;某些微服务有图形计算计算的需求,我们可以使用Neo4J;甚至可以根据需求,部分微服务使用JAVA开发,部分微服务使用NodeJS进行开发。

5.按需伸缩

​ 可以根据需求,实现细粒度的拓展。例如:系统中的某个微服务遇到了瓶颈,我们可以结合这个微服务的业务特点,增加内存、升级CPU或者是增加节点。

6.DevOps

微服务架构的挑战:

1.运维要求较高

​ 更多的服务意味着更多的运维投入。在单体架构中,只需要保证一个应用的正常运行;而在微服务中,需要保证几十个甚至是几百个服务的正常运行与协作,这个项目的运维带来了很大的挑战。

2.分布式固有的复杂性

​ 使用微服务构建的是分布式系统。对于一个分布式系统,系统容错、网络延迟、分布式事务等都给我们带来了很大的挑战

3.接口挑战成本高

​ 微服务之间通过接口进行通行。如果修改某一个微服务的API,可能所有使用了该接口的微服务都需要做调整。

4.重复劳动

​ 很多服务可能都会使用到相同的功能,而这个功能并没有达到分解为一个微服务的程度,这个时候,可能各个服务都会开发这一功能,从而导致代码重复。

微服务设计原则

单一职责

​ ref:https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)

服务自治

​ 每个微服务应该具备独立的业务能力、依赖于运行环境

轻量级通信

接口明确

​ 每个服务的对外接口应该明确定义,并尽量保持不变。

微服务开发框架浅谈

Spring Cloud:http://projects.spring.io/spring-cloud

Dubbo:http://dubbo.io

Dropwizard:http://www.dropwizard.io

Consl、etcd &etc.

Spring Cloud简介

简介

​ http://projects.spring.io/spring-cloud/

​ 快速构建分布式系统的工具集

版本

服务注册与发现

创建调用关系的微服务

这里写图片描述

服务消费者 调用别的微服务的微服务
服务提供者 提供API的微服务

使用Eureka实现服务注册与发现

这里写图片描述
https://github.com/netflix/eureka

Coding

客户端负载均衡Ribbon

这里写图片描述

https://github.com/netflix/ribbon

声明式的Http Client Feign

如果构造的URL是:
https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd=a&rsv_pq=f6979d4300002345&rsv_t=446dYzzGumwp9r132%2BoNxNq4Ht0Dy%2F0tJaCJvOXeRxJhqVMEeAYe194xKHo&rqlang=cn&rsv_enter=1&rsv_sug3=1&rsv_sug1=1&rsv_sug7=100&rsv_sug2=0&inputT=382&rsv_sug4=382
怎么办?

https://github.com/OpenFeign/feign

微服务容错

雪崩效应

这里写图片描述

实现容错的方案

  1. 为请求设置超时
    通过网络请求其他服务时,都必须设置超时。正常情况下,一个远程调用一般在几十毫秒内就能得到响应了。如果依赖的服务不可用,或者网络有问题,响应时间将会变得很长(几十秒)。
    通常情况下,一次远程调用对应着一个线程/进程。如果响应太慢,这个线程/进程就得不到释放。而线程/进程又对应着系统资源,如果得不到释放的线程/进程越积越多,服务资源就会被耗尽,从而导致服务不可用。
    因此,必须为每个请求设置超时,让资源尽快地得到释放。

  2. 使用断路器
    试想一下,如果家庭里没有断路器,电流过载了(例如功率过大、短路等),电路不断开,电路就会升温,甚至是烧断电路、起火。有了断路器之后,当电流过载时,会自动切断电路(跳闸),从而保护了整条电路与家庭的安全。当电流过载的问题被解决后,只要将关闭断路器,电路就又可以工作了。
    同样的道理,当依赖的服务有大量超时时,再让新的请求去访问已经没有太大意义,只会无谓的消耗现有资源。譬如我们设置了超时时间为1秒,如果短时间内有大量的请求(譬如50个)在1秒内都得不到响应,就往往意味着异常。此时就没有必要让更多的请求去访问这个依赖了,我们应该使用断路器避免资源浪费。
    断路器可以实现快速失败,如果它在一段时间内侦测到许多类似的错误(譬如超时),就会强迫其以后的多个调用快速失败,不再请求所依赖的服务,从而防止应用程序不断地尝试执行可能会失败的操作,这样应用程序可以继续执行而不用等待修正错误,或者浪费CPU时间去等待长时间的超时。断路器也可以使应用程序能够诊断错误是否已经修正,如果已经修正,应用程序会再次尝试调用操作。
    断路器模式就像是那些容易导致错误的操作的一种代理。这种代理能够记录最近调用发生错误的次数,然后决定使用允许操作继续,或者立即返回错误。
    断路器开关相互转换的逻辑如下图:

    这里写图片描述

Coding

API网关

Why API Gateway

http://blog.daocloud.io/microservices-2/

Zuul API Gateway

https://github.com/netflix/zuul

Coding

统一配置中心

配置的管理

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

配置的刷新

/refresh
/bus/refresh ===> amqp

最终架构

这里写图片描述

Spring Cloud是什么?

Cloud?云计算?不是

Spring boot

快速构建分布式系统的工具集

关于Spring Cloud的版本

大部分Spring软件的版本是以:主版本.次版本.增量版本.里程碑版本的形式命名

Spring Cloud Angel SR6???

Service Release

WIN7 Service Pack

Spring Cloud特点

约定优于配置

开箱即用、快速启动

适用于各种环境

PC Server

云环境

容器(Docker)

轻量级的组件

服务发现

Euraka

组件的支持很丰富,功能很齐全

配置中心

注册中心

智能路由

选型中立

服务发现

Eureka
Zookeeper
Consul

需要的技术储备

JAVA

Scala/Groovy

构建工具

Maven

Gradle(如何将Maven项目转为Gradle项目?maven -gradle gradle init –type pom)

Spring Boot

服务提供者与服务消费者

概念

服务提供者:服务的被调用方(即:为其他服务提供服务的服务)

服务调用者:服务的调用方(即:依赖其他服务的服务)

用户–购票–>电影微服务—查询用户信息–>用户微服务

编写一个服务提供者

@RequestMapping("/findById/{id}")//@PathVariable(name ="id")    public UserEntity findById(@PathVariable(name ="id") Long id){    return userRepository.findOne(id);}

编写一个服务消费者

@Autowiredprivate RestTemplate restTemplate;@RequestMapping("/findById/{id}")public UserEntity findById(@PathVariable(name = "id") Long id){    return restTemplate.getForObject("http://localhost:8080/findById/"+id,UserEntity.class);}

服务发现与服务注册

如何解决硬编码问题?

用户–购票–>电影微服务—查询用户信息–>用户微服务

服务发现

这里写图片描述

服务发现组件的功能

服务注册表

服务注册表是一个记录当前可用服务实例的网络信息的数据库,是服务发现机制的核心。服务注册表提供查询API和管理API,使用查询API获得可用的服务实例,使用管理API实现注册和注销;

服务注册

服务注册很好理解,就是服务启动时,将服务的网络地址注册到服务注册表中;

健康检查

服务发现组件会通过一些机制定时检测已注册的服务,如果发现某服务无法访问了(可能是某几个心跳周期后),就将该服务从服务注册表中移除。

服务发现的方式

客户端发现

Eureka
ZK

服务器端发现

Consul+nginx

术语解释

目前市面上的书籍,服务注册、服务发现、注册中心,在很多场景下,都可以理解为是服务发现组件。

使用Hystrix保护应用

目前存在的问题

这里写图片描述

雪崩效应

​ 在微服务架构中通常会有多个服务层调用,大量的微服务通过网络进行通信,从而支撑起整个系统。各个微服务之间也难免存在大量的依赖关系。然而任何服务都不是100%可用的,网络往往也是脆弱的,所以难免有些请求会失败。基础服务的故障导致级联故障,进而造成了整个系统的不可用,这种现象被称为服务雪崩效应。服务雪崩效应描述的是一种因服务提供者的不可用导致服务消费者的不可用,并将不可用逐渐放大的过程。

A作为服务提供者,B为A的服务消费者,C和D是B的服务消费者。A不可用引起了B的不可用,并将不可用像滚雪球一样放大到C和D时,雪崩效应就形成了。

​ 级联失败、雪崩效应

这里写图片描述

解决方案

超时机制

通过网络请求其他服务时,都必须设置超时。正常情况下,一个远程调用一般在几十毫秒内就返回了。当依赖的服务不可用,或者因为网络问题,响应时间将会变得很长(几十秒)。而通常情况下,一次远程调用对应了一个线程/进程,如果响应太慢,那这个线程/进程就会得不到释放。而线程/进程都对应了系统资源,如果大量的线程/进程得不到释放,并且越积越多,服务资源就会被耗尽,从而导致资深服务不可用。所以必须为每个请求设置超时。

断路器模式

试想一下,家庭里如果没有断路器,电流过载了(例如功率过大、短路等),电路不断开,电路就会升温,甚至是烧断电路、起火。有了断路器之后,当电流过载时,会自动切断电路(跳闸),从而保护了整条电路与家庭的安全。当电流过载的问题被解决后,只要将关闭断路器,电路就又可以工作了。

同样的道理,当依赖的服务有大量超时时,再让新的请求去访问已经没有太大意义,只会无谓的消耗现有资源。譬如我们设置了超时时间为1秒,如果短时间内有大量的请求(譬如50个)在1秒内都得不到响应,就往往意味着异常。此时就没有必要让更多的请求去访问这个依赖了,我们应该使用断路器避免资源浪费。

断路器可以实现快速失败,如果它在一段时间内侦测到许多类似的错误(譬如超时),就会强迫其以后的多个调用快速失败,不再请求所依赖的服务,从而防止应用程序不断地尝试执行可能会失败的操作,这样应用程序可以继续执行而不用等待修正错误,或者浪费CPU时间去等待长时间的超时。断路器也可以使应用程序能够诊断错误是否已经修正,如果已经修正,应用程序会再次尝试调用操作。

断路器模式就像是那些容易导致错误的操作的一种代理。这种代理能够记录最近调用发生错误的次数,然后决定使用允许操作继续,或者立即返回错误。

构思

  1. 监控 总共请求多少次,有多少次失败 假设失败率达倒10% 断路器打开
  2. 断路器的状态
  3. 分流
  4. 自我修复(断路器状态的切换)

服务发现组件:Eureka

Why Eureka?

Eureka来自生产环境

Spring Cloud对Eureka支持很好

Eureka简介

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。Spring Cloud将它集成在其子项目spring-cloud-netflix中,以实现Spring Cloud的服务发现功能。

Eureka 项目相当活跃,代码更新相当频繁,目前最新的版本是1.5.5。Eureka 2.0的版本也正在紧锣密鼓地开发中,2.0将会带来更好的扩展性,并且使用细粒度的订阅模型取代了基于拉取的模型,但是由于还没有Release,故而不作讲解。

Eureka原理

这里写图片描述

- Application Service 就相当于本书中的服务提供者(用户微服务),Application Client就相当于本书中的服务消费者(电影微服务);- Make Remote Call,可以简单理解为调用RESTful的接口;- us-east-1c、us-east-1d等是zone,它们都属于us-east-1这个region;由图可知,Eureka包含两个组件:Eureka Server 和 Eureka Client。Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。Eureka Client是一个Java客户端,用于简化与Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。Eureka Server之间将会通过复制的方式完成数据的同步。(详见Eureka高可用章节)Eureka还提供了客户端缓存的机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检测、健康检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。

Region和Zone的关系

这里写图片描述

实现一个Eureka server

实现一个Eureka Client

Ribbon

负载均衡有哪些方式

这里写图片描述

服务器端负载均衡

客户端侧负载均衡

Ribbon是什么

​ Ribbon是Netflix发布的云中间层服务开源项目,其主要功能是提供客户端侧负载均衡算法。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,Ribbon是一个客户端负载均衡器,我们可以在配置文件中列出Load Balancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。

下图展示了Eureka使用Ribbon时候的大致架构:

这里写图片描述

Ribbon工作时分为两步:第一步先选择 Eureka Server, 它优先选择在同一个Zone且负载较少的Server;第二步再根据用户指定的策略,在从Server取到的服务注册列表中选择一个地址。其中Ribbon提供了多种策略,例如轮询round robin、随机Random、根据响应时间加权等。

Ribbon示例

Server端:

1.需要的依赖的项目:(pom.xml中)        <!--eurekaServer-->        <dependencies>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-eureka-server</artifactId>        </dependency>        <!--spring security-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-security</artifactId>        </dependency>        注意:eurekaServer不能直接依赖,需要定义一些版本以及其他,建议从IDEA的spring initallier中创建并依赖,具体位置在Cloud Discovery-->Eureka Server2.项目需要定义的配置信息(application.yml/application.properties中):        server:  port: 8083    工程对外提供的访问端口eureka:  client:设置为falst表示不是客户端    register-with-eureka: false    fetch-registry: false    service-url:      defaultZone: http://user:password@localhost:8083/eureka/security:  user:    name: user  用户名称    password: password  用户密码  basic:    enabled: true 启用spring:  application:    name: microservice-discovery-eureka  工程标注名称3.在项目启动类上标注注解(xxxApplication.java):    @EnableEurekaServer

Client端:

​ 生产端:

1.需要的依赖的项目:(pom.xml中)        <!--eureka Client-->        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-eureka</artifactId>        </dependency>        <!--程序运行状态监控 actuator with the application running status ,detail with /health /info -->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-actuator</artifactId>        </dependency>2.项目需要定义的配置信息(application.yml/application.properties中):            eureka:          client:            serviceUrl:              defaultZone: http://user:password@localhost:8083/eureka 注册到server上的地址          instance:            prefer-ip-address: true              instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}  自定义instance-id,方便使用和查看信息        #    status-page-url: ${management.context-path}/info  自定义监控检测对外RESTFul的访问路径        #    health-check-url: ${management.context-path}/health3.在项目启动类上标注注解(xxxApplication.java):        @EnableDiscoveryClient4.在controller类中使用:            //需要注入客户端对象            @Autowired            private DiscoveryClient discoveryClient            //    或者使用            //    @Autowired            //    private EurekaClient eurekaClient;            

​ 消费端:

1.需要的依赖的项目:(pom.xml中)        <!--服务检测 microservice server actuator-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-actuator</artifactId>        </dependency>        <!--microservice discovery service eureka client -->        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-eureka</artifactId>        </dependency>2.项目需要定义的配置信息(application.yml/application.properties中):         server:          port: 8082        spring:          application:            name: microservice-consumer-movie        eureka:          client:            serviceUrl:              defaultZone: http://user:password@localhost:8083/eureka          instance:            prefer-ip-address: true            instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}3.在项目启动类上标注注解(xxxApplication.java):        @EnableDiscoveryClient4.为项目注入一个服务调用者:        @Bean        @LoadBalanced        public RestTemplate restTemplate(){            return new RestTemplate();        }

启动项目后可以在直接访问eureka Server的IP可以查看到服务注册引用情况

Ribbon自定义配置

1.全局配置:    在XXXApplication.java类所在路径下:        创建一个普通类,类上需要的注解如下:        @Configuration        @RibbonClient(name = "microservice-cloud1-provider",configuration = RibbonLoadBalanceConfiguration.class)        类中需要为项目注解一个bean:            @Bean            public IRule ribbonRule(IClientConfig config) {                return new RandomRule();            }2.局部配置:(可以配置多个RibbonClient)    在XXXApplication.java类上:        @RibbonClient(name = "microservice-cloud1-provider",configuration = RibbonLoadBalanceConfiguration.class)    创建一个类,不要放在XXXApplication.java的路径下,类中为项目注入Bean:            @Bean            public IRule ribbonRule(IClientConfig config) {                return new RandomRule();            }   3.通过注解标志清除:    在该配置文件类所在目录创建一个注解,比如说public @interface ExcludeFromComponentScan {}    在启动类上配置:@ComponentScan(excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, value = ExcludeFromComponentScan.class) })    在配置文件类上加上注解:@ExcludeFromComponentScan    ---------->这样的话,就算自定义的负载均衡配置类就算放在启动类的路径下也可以4.配置文件的方式(application.properties/application.yml中):    microservice-provider-user:   引入的生产者的application-name      ribbon:        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

Ribbon脱离Eureka使用

ribbon:  eureka:   enabled: falsemicroservice-provider-user:   application-name的名称  ribbon:    listOfServers: localhost:7900

使用原生的Ribbon API

    @Autowired    private LoadBalancerClient loadBalancerClient;    String message = (serviceInstance.getHost() + "--" + serviceInstance.getPort()+serviceInstance.getServiceId());

Feign

基本使用

​ 导入feign的依赖:

        <!-- feign  JAX-RS(rest service) -->        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-feign</artifactId>        </dependency>

​ XXXApplication.java上注解:

@EnableFeignClients

​ 编写一个FeignClient的接口:

@FeignClient("MICROSERVICE-CLOUD1-PROVIDER")public interface MovieFeignClient {    //不推荐使用    @RequestMapping(value = "/findById/{id}")//,method = RequestMethod.GET    UserEntity findById(@PathVariable(name = "id") Long id);    //推荐使用    @RequestLine("GET /findById/{id}")//    @Headers("Content-Type: application/json")  //请求头设置//    @Body("<login \"user_name\"=\"{user_name}\" \"password\"=\"{password}\"/>") //请求体设置    UserEntity findById_feign( @Param("id") Long id);}

​ 在controller中注入:

    @Autowired    private MovieFeignClient movieFeignClient;

源码摘抄:

@FeignClient:--->    /**     * A custom <code>@Configuration</code> for the feign client. Can contain override     * <code>@Bean</code> definition for the pieces that make up the client, for instance     * {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.     *     * @see FeignClientsConfiguration for the defaults     */    Class<?>[] configuration() default {};FeignClientsConfiguration:--->    @Configuration    public class FeignClientsConfiguration

配置认证、协议、日志

import feign.auth.BasicAuthRequestInterceptor;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class AuthenticationConfiguration {    @Bean    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {        return new BasicAuthRequestInterceptor("user", "password123");    }    @Bean    public Contract feignContract() {        return new feign.Contract.Default();    }    @Bean    Logger.Level feignLoggerLevel() {        return Logger.Level.FULL;        //需要配置如下:        logging:  level:    com.linyi.cloud1.feignClient: DEBUG    }}@FeignClient(name = "MICROSERVICE-CLOUD1-PROVIDER",configuration = AuthenticationConfiguration.class)

梳理一下上面注册的思路

eureka Client 通过标注url 在 指定的eureak Server上注册 application-name,在eureka server 配置开启了spring security 后通过输入用户名称和密码登录可以直接查看("/"),这是生产者端的,而消费者端通过注册在指定url的eureka server后引用指定application-name得到生产者的服务(也是生产者暴露的服务),而同一个application-name下可以有多个eureka client Microservice server,client 如果使用的是ribbon可以配置负载均衡策略可以合理的有规律的调用不同的eureka client,而对于消费者而言他只是知道application-name,其实也可以调用指定url的client通过在feignClient的url中指定 

配置HA

spring:  application:    name: EUREKA-HA---server:  port: 8761spring:  profiles: peer1eureka:  instance:    hostname: peer1  client:    serviceUrl:      defaultZone: http://peer2:8762/eureka/,http://peer3:8763/eureka/---server:  port: 8762spring:  profiles: peer2eureka:  instance:    hostname: peer2  client:    serviceUrl:      defaultZone: http://peer1:8761/eureka/,http://peer3:8763/eureka/---server:  port: 8763spring:  profiles: peer3eureka:  instance:    hostname: peer3  client:    serviceUrl:      defaultZone: http://peer1:8761/eureka/,http://peer2:8762/eureka/测试时需要在本地的hosts文件中加入peer1,peer2,peer3的映射

常见问题

Eureka Environment的配置

eureka.environment: 字符串

参考文档:https://github.com/Netflix/eureka/wiki/Configuring-Eureka

Eureka DataCenter的配置

# 配置-Deureka.datacenter=cloud,这样eureka将会知道是在AWS云上eureka.datacenter: cloud

参考文档:https://github.com/Netflix/eureka/wiki/Configuring-Eureka

关于Eureka自我保护

出现的提示:

​ EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE

导致的问题:

​ Eureka Server不踢出已关停的节点

如何解决Eureka Server不踢出已关停的节点的问题

​ server端:

eureka.server.enable-self-preservation          (设为false,关闭自我保护,开发、测试环境可用,建议生产环境不可用)eureka.server.eviction-interval-timer-in-ms     清理间隔(单位毫秒,默认是60*1000

​ client端:

eureka.client.healthcheck.enabled = true                开启健康检查(需要spring-boot-starter-actuator依赖)eureka.instance.lease-renewal-interval-in-seconds =10       租期更新时间间隔(默认30秒)eureka.instance.lease-expiration-duration-in-seconds =30  租期到期时间(默认90秒)

​ 示例:

服务器端配置:eureka:    server:        enableSelfPreservation: false        evictionIntervalTimerInMs: 4000客户端配置:eureka:    instance:        leaseRenewalIntervalInSeconds: 10        leaseExpirationDurationInSeconds: 30

注意

​ 更改Eureka更新频率将打破服务器的自我保护功能

参考文档:https://github.com/spring-cloud/spring-cloud-netflix/issues/373

Eureka注册服务慢的问题如何解决

​ eureka.instance.leaseRenewalIntervalInSeconds

参考文档:

​ http://cloud.spring.io/spring-cloud-static/Camden.SR1/#_why_is_it_so_slow_to_register_a_service

原文:

​ Why is it so Slow to Register a Service?Being an instance also involves a periodic heartbeat to the registry (via the client’s serviceUrl) with default duration 30 seconds. A service is not available for discovery by clients until the instance, the server and the client all have the same metadata in their local cache (so it could take 3 heartbeats). You can change the period using eureka.instance.leaseRenewalIntervalInSeconds and this will speed up the process of getting clients connected to other services. In production it’s probably better to stick with the default because there are some computations internally in the server that make assumptions about the lease renewal period.

翻译:

​ 作为实例还涉及到与注册中心的周期性心跳,默认持续时间为30秒(通过serviceUrl)。在实例、服务器、客户端都在本地缓存中具有相同的元数据之前,服务不可用于客户端发现(所以可能需要3次心跳)。你可以使用eureka.instance.leaseRenewalIntervalInSeconds 配置,这将加快客户端连接到其他服务的过程。在生产中,最好坚持使用默认值,因为在服务器内部有一些计算,他们对续约做出假设。

Eureka配置instanceId显示IP

eureka:  client:    serviceUrl:      defaultZone: http://localhost:8761/eureka/  instance:    preferIpAddress: true    instance-id: ${spring.cloud.client.ipAddress}:${server.port}

Eureka配置最佳实践总结

​ https://github.com/spring-cloud/spring-cloud-netflix/issues/203

Ribbon自定义配置

​ @Configuration和@ComponentScan包不应重叠

RestTemplate想获得一个List

​ 应该用数组,而不应该直接用List

​ 需要先构造成该目标对象类的数组,在调用Arrays.asList(原始的对象数组)转换成该对象类的集合

Feign自定义配置

​ @Configuration和@ComponentScan包不应重叠

@FeignClient不支持一些东西

​ @GetMapping等组合注解

​ 复杂对象作为一个参数

FeignClient中@PathVariable

​ 需要指定其value

Hystrix

基础 without anything

添加依赖:        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-hystrix</artifactId>        </dependency>启动类上注解开启hystrix: @EnableCircuitBreaker //开启hystrix@RequestMapping("/findById/{id}")    @HystrixCommand(fallbackMethod = "findById_fallback",commandProperties = @HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE"))    public UserEntity findById(@PathVariable(name = "id") Long id){        return restTemplate.getForObject("http://"+"microservice-cloud1-provider"+"/findById/"+id,UserEntity.class);    }    /**     * 不可用时的方法     * 方法参数、返回值类型必须相同     * @param id     * @return     */    public UserEntity findById_fallback(Long id){        UserEntity userEntity = new UserEntity();        userEntity.setId(1L);        userEntity.setName("hello hystrix");        return userEntity;    }       

Hystrix to increment Feign with fallback attribute

Hystrix的一个作用:通过设置回调方法或者说是备用方法 可以增强服务的运行平稳性

需要的hystrix的依赖就不说了

写一个类实现原来的FeignClient接口,重写之前的rest抽象方法,方法中直接写备用调用即可

在FeignClient接口的@FeignClient中添加注解属性fallback=实现了该rest类的字节码

从设计上来讲,Rest接口化标注后与阿里的dubbo十分相似,只是dubbo只支持java,实际上大部分网站投入都是java,spring cloud不会受到语言的限制,FeignClient的实现方法作为备用方法时设计的非常优美

fallbackFactory to increment fallback attribute

写一个类实现FallbackFactory接口指定泛型为rest接口

类上注解@Component

重写create方法,create(Throwable throwable),需要返回一个rest接口的实现类,为了区分fallback

写一个抽象类extends泛型rest接口

匿名或者lamda expression 构造该接口的实现类并返回,但是在这之前我们可以统一打印日志

Logger LOGGER = LoggerFactory.getLogger(HystrixClientFactory.class);HystrixClientFactory.LOGGER.info("fallback; reason was: {}", cause.getMessage());

注意:请不要将fallbackFactory与fallback属性同时使用

Dashboard

​ 在查看状态时,比如说/hystrix.stream ,我们发现内容过于文字化,难以直接分析,于是可以使用Dashboard

首先需要额外加入依赖

        <!--dashboard -->        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>        </dependency>

再在启动类上开启

@EnableHystrixDashboard注:import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;

可以使用/hystrix或者/hystrix.stream

Turbine

需要加上依赖:

<!--turbine,note:turbine has anything you need dependencies ,to ues like a single annalysis erueka client ,to do just single client --><dependency>   <groupId>org.springframework.cloud</groupId>   <artifactId>spring-cloud-starter-turbine</artifactId></dependency>

开启turbine的注解

@EnableTurbine注: import org.springframework.cloud.netflix.turbine.EnableTurbine;

注册到eureaka server 上

server:  port: 8031spring:  application:    name: microservice-hystrix-turbineeureka:  client:    serviceUrl:      defaultZone: http://user:password@localhost:8761/eureka  instance:    prefer-ip-address: trueturbine:  aggregator:    clusterConfig: default  appConfig: microservice-consumer-movie-ribbon-with-hystrix,microservice-consumer-movie-feign-with-hystrix  clusterNameExpression: "'default'"turbine.instanceUrlSuffix.MICROSERVICE-CONSUMER-MOVIE-RIBBON-WITH-HYSTRIX2: /ribbon/hystrix.streamlogging:   level:    root: INFO    com.netflix.turbine.monitor: DEBUG

另外一种配置:

management: # spring-boot-starter-acturator  port: 8081eureka:  client:    healthcheck:      enabled: true    serviceUrl:      defaultZone: http://user:password123@localhost:8761/eureka  instance:    prefer-ip-address: true    metadata-map:      management.port: 8081  

访问:

…./turbine.stream?cluster=…

Zuul

​ zull = router + filter

基本使用

Maven依赖:

<!--zull router&filter--><dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-zuul</artifactId></dependency>

依赖关系展开:

org.springframework.cloud:spring-cloud-starter-zuul:1.3.4.RELEASE:
[
org.springframework.cloud:spring-cloud-starter:1.2.3.RELEASE:
[

​ org.springframework.boot:spring-boot-starter:1.5.6.RELEASE,
​ org.springframework.cloud:spring-cloud-context:1.2.3.RELEASE,
​ org.springframework.cloud:spring-cloud-commons:1.2.3.RELEASE,
​ org.springframework.security:spring-security-rsa:1.0.3.RELEASE

],
org.springframework.boot:spring-boot-starter-web:1.5.6.RELEASE:
[

​ org.springframework.boot:spring-boot-starter-tomcat:1.5.6.RELEASE,
​ org.hibernate:hibernate-validator:5.3.5.Final,
​ com.fasterxml.jackson.core:jackson-databind:2.8.9,
​ org.springframework:spring-web:4.3.10.RELEASE,
​ org.springframework:spring-webmvc:4.3.10.RELEASE

],
org.springframework.boot:spring-boot-starter-actuator:1.5.6.RELEASE:
[

​ org.springframework.boot:spring-boot-actuator:1.5.6.RELEASE

],
org.springframework.cloud:spring-cloud-starter-hystrix:1.3.4.RELEASE:
[

​ org.springframework.cloud:spring-cloud-netflix-core:1.3.4.RELEASE,
com.netflix.hystrix:hystrix-core:1.5.12,
​ com.netflix.hystrix:hystrix-metrics-event-stream:1.5.12,
​ com.netflix.hystrix:hystrix-javanica:1.5.12

],
org.springframework.cloud:spring-cloud-starter-ribbon:1.3.4.RELEAS:
[

​ com.netflix.ribbon: ribbon:2.2.2,
com.netflix.ribbon:ribbon-core:2.2.2,
​ com.netflix.ribbon:ribbon-httpclient:2.2.2,
​ com.netflix.ribbon:ribbon-loadbalancer:2.2.2,
​ io.reactivex:rxjava:1.1.10

],
org.springframework.cloud:spring-cloud-starter-archaius:1.3.4.RELEASE:
[

​ com.netflix.archaius:archaius-core:0.7.4,
​ commons-configuration:commons-configuration:1.8,
​ com.fasterxml.jackson.core:jackson-annotations:2.8.0,
​ com.fasterxml.jackson.core:jackson-core:2.8.9,
​ com.google.guava:guava:18.0

],
com.netflix.zuul:zuul-core:1.3.0:
[

​ commons-io:commons-io:2.4,
​ org.slf4j:slf4j-api:1.7.25,
​ com.netflix.servo:servo-core:0.10.1,
​ com.netflix.netflix-commons:netflix-commons-util:0.1.1

]
]

注解开启

@EnableZuulProxy

源码分析:

@EnableCircuitBreaker   //hystrix@EnableDiscoveryClient  //Eureka Client@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Import(ZuulProxyMarkerConfiguration.class)public @interface EnableZuulProxy {}

​ 这时你就突然记起了ribbon,作为负载均衡的老大哥与这一帮兄弟就串联起来了,形成了服务管理-注册-获取(负载)-熔断器 一个微服务的基础套路

浏览器初次体验

​ http://localhost:8081/findById/1
​ {“id”:1,”username”:”user1”,”name”:”张三”,”age”:20,”balance”:100.00}

​ http://192.168.43.227:8084/microservice-provider-user/findById/1

​ {“id”:1,”username”:”user1”,”name”:”张三”,”age”:20,”balance”:100.00}

​ http://localhost:8083/

Application AMIs Availability Zones Status MICROSERVICE-GATEWAY-ZUUL n/a (1) (1) UP (1) - microservice-gateway-zuul:192.168.43.227:8084 MICROSERVICE-PROVIDER-USER n/a (1) (1) UP (1) - microservice-provider-user:192.168.43.227:8081

其他需求:

映射service到特定路径

zuul:  routes:    service名称: /特定路径名/**

严格管理代理

方法一:

zuul:  ignoredServices: '*'  # 首先直接去掉所有代理  routes:                   service名称: /特定路径名/**    # 单独一个一个的去手动写代理

方法二:

zuul:  ignoredServices: microservice-provider-user,microservice-provider-user2 # 指定不代理的service  routes:                   service名称: /特定路径名/**    # 单独一个一个的去手动写代理

方法三:

 zuul:  routes:    users:  #   名称全局唯一即可      path: /user/** #  访问路径自定义      serviceId: microservice-provider-user #   application-name

方法四:

zuul:  routes:    users:      path: /user/** # 自定义映射路径      url: http://127.0.0.1:8084/

方法五:

zuul:  routes:    users:      path: /user/**      serviceId: microservice-provider-userribbon:  eureka:    enabled: false  #   需要禁用eurekamicroservice-provider-user: #   上面代理的service-id == application-name  ribbon:    listOfServers:  #配置负载均衡的服务

方法六:

 zuul:  routes:    users:      path: /myusers/**    legacy: #   剩下来的映射      path: /**

其他配置

前缀
添加一个前缀到所有的映射上(add a prefix to all mappings)zuul.prefix #   例如/api(通过默认的在请求被转发之前这个代理前缀被从请求中剥离出来,也可以通过配置关闭它):The proxy prefix is stripped from the request before the request is forwarded by default zuul.stripPrefix=false 
大文件超时配置
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000 #   60秒ribbon:  ConnectTimeout: 3000  #   连接超时3秒  ReadTimeout: 60000    #   读超时60秒
Zuul的fallback配置
class MyFallbackProvider implements ZuulFallbackProvider {//需要自定义实现ZuulFallbackProvide    @Override    public String getRoute() {//重写getRoute方法,表明service名称        return "customers";    }    @Override    public ClientHttpResponse fallbackResponse() {        return new ClientHttpResponse() {            @Override            public HttpStatus getStatusCode() throws IOException {//返回的状态码                return HttpStatus.OK;            }            @Override            public int getRawStatusCode() throws IOException {//返回的状态码的值                return 200;            }            @Override            public String getStatusText() throws IOException {//返回的状态码的名称                return "OK";            }            @Override            public void close() {            }            @Override            public InputStream getBody() throws IOException {//向页面写的内容                return new ByteArrayInputStream(("fallback from "+this.getRoute()).getBytes());            }            @Override            public HttpHeaders getHeaders() {//设置请求头                HttpHeaders headers = new HttpHeaders();                headers.setContentType(MediaType.APPLICATION_JSON);                return headers;            }        };    }}

但是….上面这个例子是针对于单个的serviceId的,也可以写通用的fallback配置,其他是一样的只需要修改的是:getRoute方法的返回值

    @Override    public String getRoute() {        return "*";//这里也可以写null,效果是一样的    }

Sidecar

​ 附加服务/边车/增强服务

如何集成

​ 1.在pom.xml中添加maven依赖

        <!--sideCar 附加服务/边车  增强服务-->        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-netflix-sidecar</artifactId>        </dependency>

​ 2.在XXXApplication.java中注解开启

@EnableSidecar  //Sidecar源码:    @EnableCircuitBreaker   //hystrix    @EnableDiscoveryClient  //eurekaClient     @EnableZuulProxy        //zuul

作用

​ 异构微服务架构,实际上这样配置ha的时候有些麻烦

自定义 ZuulFilter

​ 写一个类继承ZuulFilter

package zuulFilter;import com.netflix.zuul.ZuulFilter;import com.netflix.zuul.context.RequestContext;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;import javax.servlet.http.HttpServletRequest;public class MyPreZuulFilter extends ZuulFilter {    //日志    private static final Logger LOGGER = LoggerFactory.getLogger(MyPreZuulFilter.class);    @Override    public String filterType() {//类型        return FilterConstants.PRE_TYPE;    }    @Override    public int filterOrder() {//优先级 数字越大越靠后        return FilterConstants.PRE_DECORATION_FILTER_ORDER-1;   // run before PreDecoration    }    @Override    public boolean shouldFilter() { //是否过滤        RequestContext ctx = RequestContext.getCurrentContext();        return !ctx.containsKey(FilterConstants.FORWARD_TO_KEY) // a filter has already forwarded                && !ctx.containsKey(FilterConstants.SERVICE_ID_KEY); // a filter has already determined serviceId    }    @Override    public Object run() {   //过滤的具体逻辑        RequestContext ctx = RequestContext.getCurrentContext();        HttpServletRequest request = ctx.getRequest();        LOGGER.info("remoteHost is {} ",request.getRemoteHost());        if (request.getParameter("foo") != null) {            // put the serviceId in `RequestContext`            ctx.put(FilterConstants.SERVICE_ID_KEY, request.getParameter("foo"));        }        return null;    }}

​ 在application.java中为context注入bean

package com.linyi.microservicegatewayzuul;import com.netflix.zuul.ZuulFilter;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.sidecar.EnableSidecar;import org.springframework.cloud.netflix.zuul.EnableZuulProxy;import org.springframework.context.annotation.Bean;import zuulFilter.MyPreZuulFilter;@SpringBootApplication  //boot@EnableZuulProxy    //zuulpublic class MicroserviceGatewayZuulApplication {    public static void main(String[] args) {        SpringApplication.run(MicroserviceGatewayZuulApplication.class, args);    }    @Bean    public ZuulFilter zuulFilter(){        return new MyPreZuulFilter();    }}

​ 实际上netflix默认也提供了很多ZuulFilter

禁用ZuulFilter

拿org.springframework.cloud.netfllix.zuul.filters.post.SendResponseFilter举例子,在application.yml中添加配置:zuul.SendResponseFilter.post.disable=true格式即为:zuul.类名.该类所处的四种类型中的一种.disable=true/false

Spring Cloud Config

​ 用于统一配置管理,其实也在spring cloud中,你还可以使用Zookeeper或者Consul,其实还有一些:百度的disconf,阿里的diamond,携程的apollo

​ 为什么用统一配置管理呢?

​ 为什么用统一配置管理呢?

​ 1.集中管理

​ 2.不同环境不同配置

​ 开发、测试、生产环境

​ 3.运行期间动态调整配置

​ 特殊情况下可以随时调整

​ 4.自动刷新

简介

​ Spring Cloud Config为分布式系统外部化配置提供了服务器端和客户端的支持,它包括Config Server和Config Client两部分。由于Config Server和Config Client都实现了对Spring Enviroment 和 propertySource抽象的映射,因此,Spring Cloud Config非常适合Spring应用程序,当然也可以与任何其他语言的应用程序配合使用。

​ Config Server是一个可横向拓展、集中式的配置服务器,它用于集中管理应用程序各个环境下的配置,默认使用Git存储配置内容(也可使用SubVersion、本地文件系统或Vault存储配置),因此可以方便的实现对配置的版本控制与内容审计。

​ Config Client是Config Server的客户端,用于操作存储在Config Server中的配置属性.

架构形式

​ Microservice 1 (Config Client)

​ Microservice 2 (Config Client)

​ Microservice 3 (Config Client)

​ –获取配置–>Config Server(dev|Stage|prod)

​ –从Git拉取对应配置–>Git Repo

Spring-Cloud-Config-Server

​ 依赖:

<dependency>      <groupId>org.springframework.cloud</groupId>      <artifactId>spring-cloud-config-server</artifactId></dependency>建议从IDEA中建立Spring Initializr,左选项卡中选择Cloud Config,然后再在右窗口中选择Config Server(服务端),而客户端对应选择Config Client

​ 注解开启:

@EnableConfigServer而客户端对应选择

​ 配置文件:

server:  port: 8081spring:  config:    name: spring-cloud-config-server    # the git repo address  cloud:    config:      server:        git:          uri: https://github.com/AndroidLinyi4001/repository1.git # file:///${user.home}/config-repo # add /  prefix in windonw environment

Spring-Cloud-Config-Client

​ 依赖:

<!--spring cloud config--><dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-config</artifactId></dependency>

​ 配置文件:

server:  port: 8082# 配置Spring Cloud Configspring:  cloud:    config:      uri: http://localhost:8081      profile: dev      label: master   # 标志 ,当后端存储是Git的时候,默认时master  application:    name: foobar

​ 注意:

​ 使用bootstrap.yml而不是application.yml,而且前者的配置不会被后者覆盖,像spring.application.name这样的配置官方推荐配置在bootstrap.yml文件中,如果没有指定的话将会去使用git仓库中的application.yml中的属性

​ 作用:

​ 这样就可以统一配置属性了

匹配模式

# 模式匹配spring:  cloud:    config:      server:        git:          uri: https://github.com/shiLinTan/repository1.git          repos:            simple: https://github.com/shiLinTan/simple            special:              pattern: special*/dev*,*special*/test*              uri: https://github.com/shiLinTan/special

​ 这样的话可以通过模式匹配简化配置管理,special*/dev..会匹配special-dev.yml文件

加密

​ 准备工作:

​ 在 http://cloud.spring.io/spring-cloud-static/Dalston.SR3/ 其中后面的是我现在使用的版本名,ctrl+F搜索 Java 8 JCE,点击下载jdk策略文件,在你本地安装的java的C:\Program Files\Java\jre1.8.0_131\lib\security文件夹中替换下载后解压的两个文件即可。

​ 修改配置文件:

​ encrypt: key: 的值即可

​ 测试:

​ symmetric key 的方式:

$ curl localhost:8888/encrypt -d symmetric_key682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda

​ full key pair 的方式:

$ curl localhost:8888/decrypt -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bdasymmetric_key

​ 使用:

生产环境下会自动解密:

yml文件中需要加''properties文件中=需要加''key: '{cipher}682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda'

​ 例如:

spring:  datasource:    username: dbuser    password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'

如果RSA非对称加密呢?

需要创建一个keyStore文件:

$ keytool -genkeypair -alias mytestkey -keyalg RSA \  -dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \  -keypass changeme -keystore server.jks -storepass letmein注意:如果在window环境下,请将\删除掉并连接好字符串,在linux环境下\的意思是换行的意思

需要将之前生成的keyStore文件复制黏贴在工程源码路径下,并做如下配置:

encrypt:  keyStore:    location: classpath:/server.jks  # 文件路径    password: letmein               # 密码    alias: mytestkey                # 别名    secret: changeme                # 私钥

安全配置-security

​ 一般连接服务器都是需要设置安全配置的,常用的安全框架有Apache Shiro、Spring Security等等,Shiro以其简单易用出名,Security以其功能强壮而且天然贴合Spring出名,这儿我使用Security做示范:

​ 使用Spring Security需要依赖的特定模块是:

<!--spring security --><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-security</artifactId></dependency>

​ 需要配置的为:

​ Server端:

# Spring Securitysecurity:  basic:    enabled: true  user:    name: username    password: password

​ Client端:

spring:  cloud:    config:      username: user        # 客户端配置方式一是直接配置,这样配置的话是优先于下面这种直接在uri中写的方式的      password: password      uri: http://user:password@localhost:8081  # 客户端配置方式二

​ 咦?为何Cloud会提供两种方式来配置呢?

当结合使用了eureka Client时,配置的url中填写只是service-id:application-name,当同时需要配置username和password时,需要加入属性username和password,详细如下 

Use Eureka increment Config

let Config Client/Server with Eureka Client

​ first,we need add a dependency in pom.xml:

<!-- microservice discory eureka client  --><dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-eureka</artifactId></dependency>

​ seconde,we need add some properties in properties.yml:

#配置eureka clienteureka:  client:    healthcheck:      enabled: true    serviceUrl:      defaultZone: http://user:password@localhost:8083/eureka  instance:    prefer-ip-address: true    instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}

手动刷新配置属性

​ add a dependency :

<!--actuator--><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-actuator</artifactId></dependency>

​ add annnotation in xxxApplication.java:

@RefreshScopeclass source :@Scope("refresh") value is :ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;

​ when the request is :

​ …/refresh

​ the configuration will refresh

自动刷新配置?

​ 依赖:

<!--spring cloud bus--><dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-bus-amqp</artifactId></dependency>

​ 添加配置:

#    配置rabbitmqspring:  rabbitmq:    host: localhost    port: 5672    username: guest    password: guest
原创粉丝点击