深入理解SpringCloud微服务架构

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包

SpringBoot

配置优先级

在命令行中传入的参数 如:java -jar storeMs.jar --server.port=8888

spring_application_json的属性java:comp/env中的jndi属性

Java的系统属性,可以通过System.getProperties()获得的内容。

操作系统的环境变量

通过random.*配置的随机属性

位于当前Jar包之外的 application-.properties文件

位于当前Jar包之内的 application-.properties文件

位于当前Jar包之外的 application.properties文件

位于当前Jar包之内的 application.properties文件

在@Configuration注解修改的类中,通过@PropertySource注解定义的属性。

应用默认属性 使用SpringApplication.setDefaultProperties定义的内容。

了解springboot的配置加载顺序,有助于理解springCloud的远程配置中心实现的原理。

监控功能

引入actuator依赖

使用相关的端点接口,查看监控的信息

监控的三种类:启动时系统配置相关、运行时个项功能的性能监控、系统的操作控制。

SpringCloud

Eureka注册服务中心 三个重要的角色:服务注册中心、服务提供者、服务消费者。

单点模式 注册服务中心只有一个。

#指定端口号

server.port=1111

#是否优先使用IP地址作为主机名的标识 默认为false

eureka.instance.preferIpAddress=true

#是否注册到eureka

#是否从eureka获取注册信息

#eureka服务器的地址(注意:地址最后面的 /eureka/ 这个是固定值)

eureka.client.serviceUrl.defaultZone=http://localhost:$/eureka/

高可用模式 服务中心可用将自己作为服务提供者,注册到相关的服务中心去。服务中心可以有多个,集群的方式。

#application-peer1.properties

spring.application.name=eureka-server

server.port=1111

eureka.client.serviceUrl.defaultZone=http://peer2:1112/eureka/

#application-peer2.properties

spring.application.name=eureka-server

server.port=1112

eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/

在有多个eureka注册服务的情况下,服务提供者需要配置所有的eureka中心

eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/

服务提供者 可以有多个服务提供者 eureka会将所有的相同名称的服务,做成一个列表的形式,ribbon可以实现负载均衡 获取服务。

spring.application.name=hello-service

eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

server.port=8082[8081]

服务消费者 通过@LoadBalanced来负载均衡

@Bean

@LoadBalanced

RestTemplate restTemplate() {

return RestTemplateMgr.getInstance().init().getTemplate();

}

服务续约

#发送心跳个server的频率 默认30秒

#两个心跳之间的时间间隔 超过则将服务摘除。 默认90秒

其他的一些配置 如:服务失效剔除、eureka的自我保护、服务下线等。

springCloud Ribbon 客户端负载均衡

RibbonEurekaAutoConfiguration 自动配置类

开启负载均衡的步骤:

多个服务提供者,注册到服务中心

服务消费者通过调用被@LoadBalanced注解修饰过的restTemplate

RestTemplate 与 Ribbon整合使用 详解

RestTemplate 基本使用 GET POST PUT DELETE

RestTemplate 与 Ribbon 整合

重点源码:LoadBalancerClient LoadBalancerAutoConfiguration

springCloud Hystrix 服务容错保护

HystrixCommand:用在依赖的服务返回单个操作结果的时候

HystrixObservableCommand:用在依赖的服务返回多个操作结果的时候

通过几个注解的方式可以简单使用断路器的功能

#程序启动的地方

@EnableCircuitBreaker

#具体需要断路器的服务方法上

@HystrixCommand(fallbackMethod = "helloFallback", commandKey = "helloKey")

#断路器被触发熔断的回调方法

public String helloFallback() {}

springCloud Feign 声明是服务调用

尚未仔细看

springCloud Zuul API网关服务

Zuul的使用

#在pom.xml引入spring-cloud-starter-zuul

#在application.properties配置

spring.application.name=api-gateway

server.port=5555

#在启动类使用@EnableZuulProxy

Zuul的主要功能有:

请求转发,即路由的功能;与服务治理框架结合,实现自动化的服务实例维护以及负载均衡的路由转发。

请求过滤,即可以当做是权限验证。权限校验与微服务业务逻辑解耦。

它作为系统的统一入口,屏蔽了系统内部各个服务的细节。

传统路由方式

zuul.routes.api-a-url.path=/api-a-url/**

面向服务的路由 使用eureka服务

zuul.routes.api-a.path=/api-a/**

zuul.routes.api-b.path=/api-b/**

zuul.routes.api-c.path=/ddd/**

eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

使用服务名称的方式 不用eureka服务治理

zuul.routes.api-d.path=/ddd/**

hello.ribbon.listOfServers=http://localhost:8001/,http://localhost:8002/

Cookie与头信息 为保证请求经过zuul转发后,还保留有Cookie Heads等信息,需要做一些配置:

#通过设置全局参数为空来覆盖默认值

zuul.senstitiveHeaders=

#通过制定路由的参数来配置 有如下两种配置

zuul.routes..customSensitiveHeaders=true

zuul.routes..senstiveHeaders=

重定向问题 spring security 和 shiro

zuul.addHostHeader=true

SpringCloud 的 Brixton会有重定向问题 Camden Dalston 则没有

Hystrix和Ribbon支持 尽量使用 path与serviceId对应 即使用面向服务的路由。

动态加载/动态路由:原理 将配置放置在git远程仓库,更新仓库的配置文件,调用refresh接口,加载新的配置信息。

#

动态过滤器:使用groovy实现。

springCloud Sleuth 分布式服务跟踪

整合使用

添加pom.xml的依赖

spring-cloud-starter-sleuth

启动eureka服务

访问 查看日志 分析日志即可看出链路调用的规则。 [trace-1,7cbdce82c9447510,7667724d864b3ec,false]

trace-1:应用名称 即application.properties中的spring.application.name的值

7cbdce82c9447510:springCloud Sleuth生成的一个ID 称为TraceID 用来标识一条请求链路

7667724d864b3ec:springCloud Sleuth生成的另外一个ID 称为SpanID 表示一个基本的工作单元 比如发送一个HTTP请求。

false:代表该信息是否要被后续的跟踪信息收集器获取和存储。

一条请求链路中 只能包含一个TraceID 可以有多SpanID

服务跟踪的实现原理

1.服务框架为每个请求创建唯一的跟踪标识。 一般是在httpHeader里标识

2.统计各个处理单元的时间耗时。 下一个单元开始 上一个单元结束。

public static final String SAMPLED_NAME = "X-B3-Sampled";

public static final String PROCESS_ID_NAME = "X-Process-Id";

public static final String PARENT_ID_NAME = "X-B3-ParentSpanId";

public static final String TRACE_ID_NAME = "X-B3-TraceId";

public static final String SPAN_NAME_NAME = "X-Span-Name";

public static final String SPAN_ID_NAME = "X-B3-SpanId";

public static final String SPAN_EXPORT_NAME = "X-Span-Export";

Sleuth抽样收集策略

1. 通过Sampler接口实现 默认使用PercentageBasedSampler

@Bean

public AlwaysSampler defaultSampler() {

return new AlwaysSampler();

}

2. 通过配置文件配置

与Logstash整合 收集日志分析

ELK平台 ElasticSearch/Logstash/Kibana这三个工具。

配置logstash对JSON格式日志的支持

与Zipkin整合 生产开发中,应该使用这个 附带有图形界面查看链路调用的服务。

四大核心组件:

1. Collector:收集器组件,主要处理从外部系统发送过来的信息,将这些信息转换成Zipkin内部处理的Span格式,以支持后续的存储、分析、展示等功能。

2. Storage:存储组件,主要处理收集器收到的信息,默认会将这些信息存储在内存中。可以修改存储的策略,通过使用其他存储组件,将跟踪信息存储到数据库中。

3. Restful API:API组件,童工外部访问接口。

4. WEB UI:UI组件,基于API组件实现的上层应用。方便用户查询、分析跟踪信息。

Sleuth与Zipkin整合 HTTP方式。

1. 搭建ZipKinServer 服务

zipkin-server

zipkin-autoconfigure-ui

2. 为应用引入和配置ZipKin服务

Sleuth与Zipkin整合 消息中间件收集

1. 为具体应用添加pom依赖:

spring-cloud-sleuth-stream

spring-cloud-starter-stream-rabbit

2. 配置rabbitmq服务:

3. 修改zipkin-server的pom依赖:

spring-cloud-sleuth-zipkin-stream

spring-cloud-starter-stream-rabbit

zipkin-autoconfigure-ui

API接口

springboot + elasticsearch全文检索

Elasticsearch与关系型数据库的比对

Relational DB -> Databases -> Tables -> Rows -> Columns

Elasticsearch -> Indices -> Types -> Documents -> Fields

Elasticsearch集群可以包含多个索引(indices)(数据库) ,每一个索引可以包含多个类型(types)(表) ,每一个类型包含多个文档(documents)(行) ,然后每个文档包含多个字段(Fields)(列) 。

DSL查询(Query DSL) DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现

高亮(highlight)匹配

短语搜索

全文搜索

分析 聚合 在数据上生成复杂的分析统计

自动配置类

框架整合

POM.xml的配置

spring-boot-starter-parent

1.5.2.RELEASE

spring-boot-starter-data-elasticsearch

spring-boot-starter-test

jna

3.0.9

application.properties

spring.data.elasticsearch.properties.path.logs=./elasticsearch/logs

spring.data.elasticsearch.properties.path.data=./elasticsearch/data

#独立服务或者是es集群的时候打开配置 cluster-name 必须与es配置的name一致

注解说明

@Document

@Persistent

@Inherited

@Retention(RetentionPolicy.RUNTIME)

@Target()

public @interface Document {

String indexName();//索引库的名称,一般用项目的名称命名

String type() default "";////类型,一般用实体的名称命名

boolean useServerConfiguration() default false;short shards() default 5;//默认分区数

short replicas() default 1;//每个分区默认的备份数

String refreshInterval() default "1s";//刷新间隔

String indexStoreType() default "fs";//索引文件存储类型

boolean createIndex() default true;

}

@Field

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.FIELD)

@Documented

@Inherited

public @interface Field {

FieldType type() default FieldType.Auto;//自动检测属性的类型

FieldIndex index() default FieldIndex.analyzed;//默认情况下分词

DateFormat format() default DateFormat.none;String pattern() default "";

boolean store() default false;//默认情况下不存储原文

String searchAnalyzer() default "";//指定字段搜索时使用的分词器

String analyzer() default "";//指定字段建立索引时指定的分词器

String[] ignoreFields() default {};//指定需要忽略的字段

boolean includeInParent() default false;}

springCloud 与 springBoot问题汇总

zuul 与 eureka 使用的springCloud版本需要对应上,否则容易引起Ribbon的hystrix熔断机制。

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20171216G04V6P00?refer=cp_1026

扫码关注云+社区