随着公司的业务发展,有幸经历了从单体应用迁移到分布式应用,又从分布式应用开始准备搭建微服务应用,以下是公司从零开始搭建微服务的过程,记录并分享出来,希望对大家有所帮助,我们先使用Spring Cloud GateWay作为网关,由于目前还没有服务发现组件,例如eurka,所以需要通过配置文件的方式配置Ribbon作负载均衡。所以以下重点讲解Spring Cloud GateWayRibbon的搭配使用。

网关的由来

微服务提出后,单体应用被拆分成多个服务,为了对外提供统一入口,解耦客户端与内部服务。

单体架构到微服务架构演变

网关的作用

网关能做统一的路由转发、熔断、限流、安全认证、日志监控等。

网关的作用

网关zuul与Spring Cloud Gateway对比

zuul与Spring Cloud Gateway对比

Spring Cloud Gateway核心概念

网关核心概念

1.路由(route) 路由是网关最基础的部分,路由信息由一个ID、一个目的URL、一组断言工厂和一组Filter组成。如果断言为真,则说明请求URL和配置的路由匹配。

2.断言(predicates) Java8中的断言函数,Spring Cloud Gateway中的断言函数输入类型是Spring5.0框架中的ServerWebExchange。Spring Cloud Gateway中的断言函数允许开发者去定义匹配来自Http Request中的任何信息,比如请求头和参数等。

3.过滤器(filter) 一个标准的Spring webFilter,Spring Cloud Gateway中的Filter分为两种类型,分别是Gateway Filter和Global Filter。过滤器Filter可以对请求和相应进行处理。

Spring Cloud Gateway工作原理

网关工作原理

Spring Cloud Gateway核心处理流程如上图所示,Gateway的客户端向Spring Cloud Gateway发送请求,请求首先被HttpWebHandlerAdapter进行提取组装成网关上下文,然后网关的上下文会传递到DispatcherHandler。DispatcherHandler是所有请求的分发处理器,DispatcherHandler主要负责分发请求对应的处理器。比如请求分发到对应的RoutePredicateHandlerMapping(路由断言处理映射器)。路由断言处理映射器主要作用用于路由查找,以及找到路由后返回对应的FilterWebHandler。FilterWebHandler主要负责组装Filter链并调用Filter执行一系列的Filter处理,然后再把请求转到后端对应的代理服务处理,处理完毕之后将Response返回到Gateway客户端。

路由断言Factories整理

  • After 路由断言 Factory:在该日期时间之后发生的请求都将被匹配。
  • Before 路由断言 Factory:在该日期时间之前发生的请求都将被匹配。
  • Between 路由断言 Factory:在datetime1和datetime2之间的请求将被匹配。
  • Cookie 路由断言 Factory:Cookie 路由断言 Factory有两个参数,cookie名称和正则表达式。请求包含以cookie名称且正则表达式为真的将会被匹配。
  • Header 路由断言 Factory:Header 路由断言 Factory有两个参数,header名称和正则表达式。请求包含以header名称且正则表达式为真的将会被匹配。
  • Host 路由断言 Factory:Host 路由断言 Factory包括一个参数:host name列表。使用Ant路径匹配规则,.作为分隔符。
  • Method 路由断言 Factory:Method 路由断言 Factory只包含一个参数: 需要匹配的HTTP请求方式。
  • Path 路由断言 Factory:Path 路由断言 Factory 有2个参数: 一个Spring PathMatcher表达式列表和可选。
  • Query 路由断言 Factory:Query 路由断言 Factory 有2个参数: 必选项 param 和可选项 regexp。
  • RemoteAddr 路由断言 Factory:RemoteAddr 路由断言 Factory的参数为 一个CIDR符号(IPv4或IPv6)字符串的列表,最小值为1,例如192.168.0.1/16(其中192.168.0.1是IP地址并且16是子网掩码)。

GatewayFilter Factories整理

  • AddRequestHeader GatewayFilter Factory:对于所有匹配的请求,这将向下游请求的头中添加header。
  • AddRequestParameter GatewayFilter Factory:对于所有匹配的请求,这将向下游请求添加查询字符串。
  • AddResponseHeader GatewayFilter Factory:对于所有匹配的请求,这会将头添加到下游响应的header中。
  • Hystrix GatewayFilter Factory:Hystrix 是Netflix开源的断路器组件。Hystrix GatewayFilter允许你向网关路由引入断路器,保护你的服务不受级联故障的影响。
  • FallbackHeaders GatewayFilter Factory:FallbackHeaders允许在转发到外部应用程序中的FallbackUri的请求的header中添加Hystrix异常详细信息。
  • PrefixPath GatewayFilter Factory:这将给所有匹配请求的路径加前缀。
  • PreserveHostHeader GatewayFilter Factory:该filter没有参数。设置了该Filter后,GatewayFilter将不使用由HTTP客户端确定的host header ,而是发送原始host header 。
  • RequestRateLimiter GatewayFilter Factory:RequestRateLimiter使用RateLimiter实现是否允许继续执行当前请求。如果不允许继续执行,则返回HTTP 429 - Too Many Requests (默认情况下)。
  • Redis RateLimiter:令牌桶的填充速率。
  • RedirectTo GatewayFilter Factory:该过滤器有一个 status 和一个 url参数。status是300类重定向HTTP代码,如301。该URL应为有效的URL,这将是 Location header的值。
  • RemoveRequestHeader GatewayFilter Factory:有一个name参数. 这是要删除的header的名称。
  • RemoveResponseHeader GatewayFilter Factory:有一个name参数. 这是要删除的header的名称。
  • RewritePath GatewayFilter Factory:包含一个 regexp正则表达式参数和一个 replacement 参数. 通过使用Java正则表达式灵活地重写请求路径。
  • RewriteResponseHeader GatewayFilter Factory:包含 name, regexp和 replacement 参数.。通过使用Java正则表达式灵活地重写响应头的值。
  • SetPath GatewayFilter Factory:它提供了一种通过允许路径的模板化segments来操作请求路径的简单方法。使用Spring Framework中的URI模板,允许多个匹配segments。
  • SetStatus GatewayFilter Factory:SetStatus GatewayFilter Factory 包括唯一的 status参数.必须是一个可用的Spring HttpStatus。
  • StripPrefix GatewayFilter Factory:parts参数指示在将请求发送到下游之前,要从请求中去除的路径中的节数。
  • Retry GatewayFilter Factory:Retry GatewayFilter Factory包括 retries, statuses, methods和 series 参数。
  • RequestSize GatewayFilter Factory:当请求大小大于允许的限制时,RequestSize GatewayFilter Factory可以限制请求不到达下游服务。过滤器以RequestSize作为参数,这是定义请求的允许大小限制(以字节为单位)。

Ribbon的LoadBalancer的主要组件

Ribboon主要组件

IPing:客户端用于快速检查服务器当时是否处于活动状态(心跳检测)IRule:负载均衡策略,用于确定从服务器列表返回哪个服务器ServerList:可以响应客户端的特定服务的服务器列表ServerListFilter:可以动态获得的具有所需特征的候选服务器列表的过滤器ServerListUpdater:用于执行动态服务器列表更新

IRule

RoundRobinRule:系统默认的规则,通过简单轮询服务列表来选择服务器。AvailabilityFilteringRule:该规则会忽略一下服务器。无法连接的服务器。默认情况下,3次连接失败,服务器会被置为短路的状态,状态持续为30秒;再次连接失败,短路的状态持续时间将会以几何数增加。可以通过修改connectionFailureCountThreshold属性,配置连接失败的次数。并发数过高的服务器。可以修改ActiveConnectionsLimit属性来设置最高并发数。WeightedResponseTimeRule: 为每个服务器赋予一个权重值,服务器的响应时间越长,权重就越小,随机选择服务器,权重值有可能会决定服务器的选择。ZoneAvoidanceRule: 该规则以区域、可用服务器为基础进行服务器选择。使用Zone对服务器进行分类。BestAvailableRule: 忽略短路的服务器,并选择并发数较低的服务器。RandomeRule: 随机选择可用的服务器。RetryRule: 含有重试的选择逻辑。

IPing

检查实例是否存活。如何ping。实现类:

NoOpPing: 不进行Ping。DummyPing:默认实现,标记存活的服务器。NIWSDiscoveryPing: 假设服务器存活。PingUrl: 一种健康检查的ping。

ServerList

获取服务器列表。

DiscoveryEnabledNIWSServerList: 从Eureka 客户端获取服务器列表。DomainExtractingServerList: 基于domain获取服务列表。ConfigurationBasedServerList: 从配置中获取服务器列表

ServerListFilter

在获取的服务器列表中进行获取。

ZoneAffinityServerListFilter: 根据区域亲缘关系过滤服务器。在使用这个过滤器时,需要开启CommonClientConfig#EnableZoneAffinity或者
CommonClientConfigKey#EnableZoneExclusivity=true。开启后,同一个区域之外的服务器将被过滤。默认情况下,区域亲和力和排他性是关闭的,并且
不会过滤任何内容。ZonePreferenceServerListFilter: 主动首选本地区域的过滤器。ServerListSubSetFilter: 服务器列表过滤器,将负载均衡器使用的服务器数量限制为所有服务器的子集。

ServerListUpdater

更新服务器列表。

EurekaNotificationServerListUpdater: 利用Eureka的时间监听器触发LB缓存更新。PollingServerListUpdater: 默认的策略动态更新服务器列表。

IClientConfig

  • IClientConfig的实现类为DefaultClientConfigImpl。DefaultClientConfigImpl是默认的客户端配置,可以从Archaius ConfigurationManager加载属性。

ILoadBalancer

LoadBalancer的组成:

  1. 一个基于特定条件可能进行存储的服务器列表。
  2. 一个类:通过IRule实现并定义LoadBalancing策略。
  3. 该类定义并实现一种机制,用户确定列表中节点/服务器的实用性/可用性。

LoadBalancer的实现类:

BaseLoadBalancer: 基本的实现,ping确定存活的服务器列表。DynamicServerListLoadBalancer: 动态获取的服务器列表。ZoneAwareLoadBalancer: LoadBalancer将计算并检查所有可用区域的区域统计信息。如果任何区域的“平均活动请求数”已达到配置的阈值,
则该区域将从活动服务器列表中删除。如果多个区域已达到阈值,则将删除每台服务器上最活跃请求的区域。一旦删除了最坏的区域,
将在其余区域中选择一个区域,其概率与其实例数成正比。服务器将从具有指定规则的选定区域返回。每个区域相关的负载平衡决策都是在最新统计信息的帮助下实时做出的。

代码实践

pom.xml增加SpringCloud Gateway和Ribbon依赖

org.springframework.boot    spring-boot-starter-parent    2.0.3.RELEASEorg.springframework.boot            spring-boot-starter        org.springframework.boot            spring-boot-starter-actuator        org.springframework.cloud            spring-cloud-starter-gateway        org.springframework.cloud            spring-cloud-starter-netflix-ribbon        

代码方式配置网关

@SpringBootApplication@RestControllerpublic class DemoGatewayApplication {    public static void main(String[] args) {        SpringApplication.run(DemoGatewayApplication.class, args);    }   @Bean   public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {        return builder.routes()            .route(r -> r                .path("/refund/**")                .filters(f -> f.addRequestHeader("Hello", "World"))                .uri("http://manage-test.payplatform.speiyou.cn/")            ).build();    }}

yml方式配置网关

spring:  application:    name: gateway-service  cloud:    gateway:      routes:      - id: merchant        uri: lb://merchant-load-balanced-service        predicates:        - Path=/merchant/**        - Method=POST      - id: split        uri: lb://split-load-balanced-service        predicates:        - Path=/split/**        filters:        - RewritePath=/split, /ledger-split #重写url      - id: cashier        uri: lb://cashier-load-balanced-service        predicates:        - Path=/cashier/**        filters:        - StripPrefix=1 #将cashier过滤掉        #ribbon全局配置ribbon:  ConnectTimeout: 1000 #服务请求连接超时时间(毫秒)  ReadTimeout: 3000 #服务请求处理超时时间(毫秒)  OkToRetryOnAllOperations: true #对超时请求启用重试机制  MaxAutoRetriesNextServer: 1 #切换重试实例的最大个数  MaxAutoRetries: 1 # 切换实例后重试最大次数  NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #负载均衡算法  NFLoadBalancerPingClassName: com.talpay.gateway.config.HealthCheck   #健康检查  NFLoadBalancerPingInterval: 20                                       #设置健康检查间隔,单位秒,默认30秒merchant-load-balanced-service:  ribbon:    listOfServers: 192.168.xxx.xxx:8080split-load-balanced-service:  ribbon:    listOfServers: 192.168.xxx.xxx:8081cashier-load-balanced-service:  ribbon:    listOfServers: 192.168.xxx.xxx:8080

Ribbon服务健康检查

@Slf4j@Componentpublic class HealthCheck implements IPing{    @Autowired    private RestTemplate restTemplate;    @Value("${dingtalk.url}")    private String dingtalkURL; //钉钉报警url    @Override    public boolean isAlive(Server server) {               String url = "http://"+ server.getId()+ "/actuator/health";        try {            ResponseEntity heath = restTemplate.getForEntity(url, String.class);            if (heath.getStatusCode() == HttpStatus.OK) {                log.info("ping " + url + " success ");                return true;            }            log.info("ping " + url + " error and response is " + heath.getBody());            return false;        } catch (Exception e) {            log.error("ping " + url + " failed");            DingRebotSendUtil.send(dingtalkURL,new TextMessage("网关|ping:" + url + " failed"));            return false;        }    }}

自定义GlobalFilter

@Componentpublic class LogGlobalFilter implements GlobalFilter {    @Override    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {        ServerHttpRequest serverHttpRequest= exchange.getRequest();        String url = serverHttpRequest.getURI().toString();        System.out.println("url ------>: " + url);//打印每次请求的url        return chain.filter(exchange);    }}

测试结果:

第一次触发

第二次触发

以上为真实测试数据,第一次触发链接到生产环境,第二次触发链接到仿真环境。

不断分享开发过程用到的技术和面试经常被问到的问题,如果您也对IT技术比较感兴趣可以「关注」我

请求失败或服务未及时响应 有关详细信息_「干货」从零开始的微服务搭建之路...相关推荐

  1. 请求失败或服务未及时响应 有关详细信息_微服务治理与统计分析

    转载本文需注明出处:微信公众号EAWorld,违者必究. 引言: 微服务架构下,服务拆得越细,服务的粒度越小,可组装性就越好:与之相对的服务之间的调用关系就会变复杂,为了保证服务更好的运行,需要对这些 ...

  2. SQL 2008 R2 启动失败 提示 请求失败或服务未及时响应

    为什么启动sql server 配置管理器出现请求失败或服务未及时响应_百度知道 http://zhidao.baidu.com/link?url=ElemzIan6I2CqJsd7-7uk5TV25 ...

  3. 连接到服务器 ------------------------------ 无法连接到 + SQL Server 请求失败或服务未及时响应....解决思路

    今天想打开SQL SERVER 写写数据库的代码.结果按照之前的连接方法 死活连接不上,windows登录和SQL身份认证都是一样的. 于是猜测是因为sql本身服务的问题. 就打开了win + r 输 ...

  4. 请求失败或服务未及时响应。有关详细信息,请参见事件日志或其他适用的错误日志。

    请求失败或服务未及时响应.有关详细信息,请参见事件日志或其他适用的错误日志. 第一步:怎么查看系统日志信息 计算机--管理--事件查看器--Windows日志--应用程序. 第二步:根据系统提供的日志 ...

  5. SQL SERVER服务启动不了:请求失败或服务未及时响应。有关详细信息请参见事件日志或其他的错误日志

    不知怎么回事,SQL SERVER服务启动不了,提示:请求失败或服务未及时响应.有关详细信息请参见事件日志或其他的错误日志.在网上找好久才找到答案:停用"VIA协议"问题解决. 停 ...

  6. 代码重新发布后docker服务会不会受影响_分享点经验 | 浅谈微服务架构

    点击蓝字关注我们 AMP 背景简介 在最原始的系统设计中,我们通常使用单体架构.单体架构把所有的业务逻辑都写在一起,没有对业务场景进行划分.在规模比较小的情况下工作情况良好,但是随着系统规模的扩大,它 ...

  7. 入门、复习微服务的同学看过来,一篇文章让你彻底搞懂微服务

    废话不多说,各位先看下微服务的简介 微服务简介 微服务是一种经过良好架构设计的分布式架构方案,微服务架构特征: 单一职责:微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务 ...

  8. ios11修改微信步数_基于天宫的星舟微服务方案介绍

     微服务架构模式 面对单体架构带来的诸如应用更新周期长,无法针对单独的功能进行扩展和配置资源,无法弹性伸缩应用的负载能力,一个模块故障造成整个应用的不可用,难以采用新技术等等挑战,我们采用微服务架构模 ...

  9. 从零开始学习微服务 -微服务基本概述、微服务案例

    1. SpringCloud概述 1.1 互联网应用架构 1.1.1 单体应用架构 在诞⽣之初,项目的⽤户量.数据量规模都⽐较⼩,项目所有的功能模块都放在一个工程中编码. 编译.打包并且部署在一个To ...

最新文章

  1. Eclipse如何从SVN更新和上传修改部分项目
  2. 由浅入深:自己动手开发模板引擎——置换型模板引擎(四)
  3. ORACLE普通表转换成分区表
  4. Android中利用正则表达式验证手机号是否合法
  5. NDK/JNI01--NDK下载配置
  6. memchache的数据类型_memcache详解
  7. Python案例:用米粒填充国际象棋盘
  8. 用 document.readyState == complete 判断页面是否加载完成。
  9. 洛谷P1938 找工就业
  10. electron 改变窗体 大小_「Science子刊」约翰·霍普金斯大学创造灰尘大小设备,可协助药物在胃肠道停留24小时之久...
  11. 一个关于超级英雄题材电影剧本的脑洞
  12. linux clock命令,Centos Linux下使用date/clock/hwclock命令设置系统和硬件时间
  13. iOS开发_UI_AutoLayout
  14. 做手机系统,鸿蒙怎样才有机会
  15. autohotkey循环
  16. 关于Android P Auto锁屏Global.DEVICE_PROVISIONED
  17. 计算机学院表白情书,大学各专业的表白情书!啊,我的少女心要炸了…
  18. 菜鸟Java开发人员的找工作之旅(1)
  19. 作者:Scott Hanselman首席工程师
  20. push()与pop()的使用

热门文章

  1. 数据级并行--计算机体系结构
  2. js vue将后台返回的url图片地址以图片形式保存到本地
  3. 停车管理系统汽车到达汽车离去c语言,停车场管理系统 C语言实现
  4. 链式运动JavaScript实现
  5. 向一个对象数组里面添加新的属性 + 将一个对象数组数据拿出来变成另一个对象
  6. 中石油计算机组成原理a在线考试,计算机组成原理试题A.doc
  7. .NET Core采用的全新配置系统[7]: 将配置保存在数据库中
  8. vcf文件(call variants得来的)怎么看变异是纯合还是杂合的
  9. 说说第二次配置Ubuntu14.04
  10. mybaits trim用法