SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)

文章目录

  • SpringCloudAlibaba下篇(GateWay,Skywalking)
    • 1 GateWay
      • 1.1 什么是网关
      • 1.2 GateWay介绍
      • 1.3 GataWay的基本使用
      • 1.4 GataWay整合Nacos
      • 1.5 断言路由工厂
        • 1.5.1 内置断言路由工厂
        • 1.5.2 自定义断言路由工厂
      • 1.6 过滤器工厂
        • 1.6.1 内置局部过滤器工厂
        • 1.6.2 自定义局部过滤器
        • 1.6.3 内置全局过滤器工厂
        • 1.6.4 自定义全局过滤器
      • 1.7 Gateway跨域配置
      • 1.8 Gataway整合sentinel流控降级
    • 2 SkyWalking
      • 2.1 什么是SkyWalking
      • 2.2 SkyWalking服务端搭建
        • 2.2.1 下载SkyWalking
        • 2.2.2 目录结构
        • 2.2.3 接入微服务
        • 2.2.4 使用mysql持久化
        • 2.2.5 自定义链路追踪
      • 2.3 告警

SpringCloudAlibaba下篇(GateWay,Skywalking)

1 GateWay

1.1 什么是网关

⼤家都知道的是在微服务架构中,⼀个系统会被拆分为很多个微服务。那么作为客户端要如何去调⽤这么多的微服务呢?如果没有⽹关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调⽤。

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第1张图片

这样的架构,存在的问题

① 每个业务都会需要鉴权、限流、权限校验、跨域等逻辑,如果每个业务都各自为战,自己造轮子实现一遍,会很蛋疼,完全可以抽出来,放到一个统一的地方去做。

② 如果业务量比较简单的话,这种方式前期不会有什么问题,但随着业务越来越复杂,比如淘宝、亚马逊打开一个页面可能会涉及到数百个微服务协同工作,如果每一个微服务都分配一个域名的话,一方面客户端代码会很难维护,涉及到数百个域名,另一方面是连接数的瓶颈,想象一下你打开一个APP,通过抓包发现涉及到了数百个远程调用,这在移动端下会显得非常低效.

③ 后期如果需要对微服务进行重构的话,也会变的非常麻烦,需要客户端配合你一起进行改造,比如商品服务,随着业务变的越来越复杂,后期需要进行拆分成多个微服务,这个时候对外提供的服务也需要拆分成多个,同时需要客户端配合你进行改造,非常蛋疼。

网关就是用来解决上述问题的

关注稳定与安全

  • 全局性流控
  • 日志统计
  • 防止SQL注入
  • 防止Web攻击
  • 屏蔽工具扫描
  • 黑白IP名单
  • 证书/加解密处理

提供更好的服务

  • 服务级别流控
  • 服务降级与熔断
  • 路由与负载均衡、灰度策略
  • 服务过滤、聚合与发现
  • 权限验证与用户等级策略
  • 业务规则与参数校验
  • 多级缓存策略

所谓的API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控路由转发等等。
添加上API网关之后,系统的架构图变成了如下所示:

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第2张图片

1.2 GateWay介绍

Spring Cloud Gateway是由WebFlux + Netty + Reactor实现的响应式的API网关。它不能在传统的servlet容器中工作,也不能构建成war包

Spring Cloud Gateway旨在为微服务架构提供一种简单且有效的API路由的管理方式,并基与Filter提供网关的基本功能,例如说安全认证、监控、限流等等。

用来代提Zuul的,性能是zuul的1.6倍

Spring Cloud Gateway 功能特征

  • 基于Spring Framework 5,Project Reactor和 Spring Boot 2.0进行构建;
  • 动态路由:能够匹配任何请求属性;
  • 支持路径重写;
  • 集成Spring Cloud服务发现功能(Nacos、Eruka) ;
  • 可集成流控降级功能(Sentinel、Hystrix) ;
  • 可以对路由指定易于编写的Predicate(断言)和Filter (过滤器);

路由(route)

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

断言(predicates)

  • Java8中的断言函数,SpringCloud Gateway中的断言函数美型是Spring5.0框架中的SeverWebExchange。断言函数允许开发者去定义匹配Http request中的任何信息,比如请求头和参数等

过滤器(Filter)

  • SpringCloud Gateway中的filter分为Gateway Filler和Global Filter。Filter可以对请求和响应进行处理。

Gateway核⼼架构

路由( Route ) 是 gateway 中最基本的组件之⼀,表示⼀个具体的路由信息载体。主要定义了下⾯的⼏个信息:

id:路由标识符,区别于其他 Route 。

uri:路由指向的⽬的地 uri ,即客户端请求最终被转发到的微服务。

order:⽤于多个 Route 之间的排序,数值越⼩排序越靠前,匹配优先级越⾼。

predicate:断⾔的作⽤是进⾏条件判断,只有断⾔都返回真,才会真正的执⾏路由。

filter:过滤器⽤于修改请求和响应信息。

  • 执行流程

1.3 GataWay的基本使用

① 引入依赖

    <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-gatewayartifactId>
    dependency>

② 配置GataWay

spring:
  application:
    name: huozhexiao-gateway
  cloud:
    gateway:
      routes: #路由规则列表,指定当请求满足条件转到对应服务
        - id: order-router   # 路由唯一标识
          uri: http://localhost:7001 #需要转发的地址
          # 配置断言,用于路由规则匹配
          predicates:
            - Path=/order-server/**
            # http://localhost:7010/order-server/order/add 路由到↓
            # http://localhost:7001/order-server/order/add
          filters:
            - StripPrefix=1 #转发前去掉第一层路径
#        - id: stock-router

访问:http://localhost:7010/order-server/order/add

1.4 GataWay整合Nacos

① 引入依赖

 		
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-loadbalancerartifactId>
        dependency>

② 配置Nacos和GataWay整合

spring:
  application:
    name: huozhexiao-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.198.129:4399
        password: nacos
        username: nacos
    gateway:
      routes: #路由规则列表,指定当请求满足条件转到对应服务
        - id: order-router   # 路由唯一标识
#        - id: stock-router
          uri: lb://order-service #需要转发的地址 lb:负载均衡
          # 配置断言,用于路由规则匹配
          predicates:
            - Path=/order-server/**
            # http://localhost:7010/order-server/order/add 路由到↓
            # http://localhost:7001/order-server/order/add
          filters:
            - StripPrefix=1 #转发前去掉第一层路径
      

访问:http://localhost:7010/order-server/order/add

  • 简写
spring:
  application:
    name: huozhexiao-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.198.129:4399
        password: nacos
        username: nacos
     gateway:
        discovery:
		  locator:
 		     enabled: true # 让gateway可以发现nacos中的微服务

访问:http://localhost:7010/order-server/order/add

1.5 断言路由工厂

作用:当请求 gateway 时, 使用断言进行匹配,如果匹配成功正常路由转发,反之返回404

类型:

内置断言路由工厂

自定义路由断言工厂

1.5.1 内置断言路由工厂

SpringCloud Gateway 包括许多内置的断⾔⼯⼚,所有这些断⾔都与 HTTP 请求的不同属性匹配。具体如下:

  • 基于Datetime类型的断⾔⼯⼚

此类型的断⾔根据时间做判断,主要有三个:

AfterRoutePredicateFactory: 接收⼀个⽇期参数,判断请求⽇期是否晚于指定⽇期。 BeforeRoutePredicateFactory: 接收⼀个⽇期参数,判断请求⽇期是否早于指定⽇期。 BetweenRoutePredicateFactory: 接收两个⽇期参数,判断请求⽇期是否在指定时间段内。

predicates:
  - After=2023-05-27T23:16:55.889-07:00[Asia/Shanghai] # 匹配上海时间2023年5月27日23:16之后提出的请求
  - Before=2023-05-27T23:16:55.889-07:00[Asia/Shanghai] # 匹配上海时间2023年5月27日23:16之前提出的请求
  - Between=2023-05-27T23:16:55.889-07:00[Asia/Shanghai], 2023-05-30T23:16:55.889-07:00[Asia/Shanghai]   #匹配上海时间2023年5月27日23:16-上海时间2023年5月30日23:16之间提出的请求
  • 基于Cookie的断⾔⼯⼚

CookieRoutePredicateFactory:接收两个参数, cookie 名字和⼀个正则表达式。

predicates:
 - Cookie=huozhexiao, hu. #匹配具有名为huozhexiao其值与hu.正则表达式
  • 基于Header的断⾔⼯⼚

HeaderRoutePredicateFactory:接收两个参数,标题名称和正则表达式。 判断请求 Header 是否具有给定名称且值与正则表达式匹配。

predicates:
 - Header=X-Request-Id, \d+ #匹配有一个名为X-Request-Id其值与\d+正则表达式的请求
  • 基于Host的断⾔⼯⼚

HostRoutePredicateFactory:接收⼀个参数,主机名模式。判断请求的 Host 是否满⾜匹配规则。

predicates:
 - Host=**.baidu.com #匹配是否是来源于baidu.com的请求。
  • 基于Method请求⽅法的断⾔⼯⼚

MethodRoutePredicateFactory:接收⼀个参数,判断请求类型是否跟指定的类型匹配。

predicates:
 - Method=GET #只接收get请求
  • 基于Path请求路径的断⾔⼯⼚

PathRoutePredicateFactory:接收⼀个参数,判断请求的 URI 部分是否满⾜路径规则。

predicates:
 - Path=/huozhexiao/* # 只有请求路径中带有huozhexiao的请求被接受
  • 基于Query请求参数的断⾔⼯⼚

QueryRoutePredicateFactory :接收两个参数,请求 param 和正则表达式, 判断请求参数是否具有给定名称且值与正则表达式匹配。

predicates:
 - Query=name, huozhe.+ # 请求参数中必须有name参数,并且名称中要以huozhe开头
  • 基于远程地址的断⾔⼯⼚

RemoteAddrRoutePredicateFactory:接收⼀个 IP 地址段,判断请求主机地址是否在地址段中。根据请求 IP 进⾏路由判断,接收 CIDR 表示法( IPv4 或 IPv6 )的字符串列表(列表最⼩⻓度为1)作为参数, 例如 192.168.1.6/ 24 , 其中 192.168.1.6 是 IP 地址, 24 是⼦⽹掩码。

predicates:
 - RemoteAddr=192.168.1.1/24  # 匹配请求的远程地址是,192.168.1.(1-25)
  • 基于路由权重的断⾔⼯⼚

WeightRoutePredicateFactory:接收⼀个[组名,权重], 然后对于同⼀个组内的路由按照权重转发。

spring:
  cloud:
    gateway:
      routes:
      - id: weight_high
        uri: https://weighthigh.org
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: https://weightlow.org
        predicates:
        - Weight=group1, 2

这条路线将把大约80%的流量转发到weighthigh.org约20%的流量流向weighlow.org

  • XForwarded远程地址路由断言工厂

XForwarded Remote Addr路由谓词工厂采用以下列表(最小大小为1)sources,这是CIDR符号(IPv4或IPv6)字符串,例如192.168.0.1/16(哪里192.168.0.1是IP地址,并且16是子网掩码)。

这个路由谓词允许根据X-Forwarded-ForHTTP头。

这可以用于反向代理,如负载平衡器或web应用程序防火墙,其中只有当请求来自这些反向代理使用的IP地址的可信列表时,才应该允许该请求。

spring:
  cloud:
    gateway:
      routes:
      - id: xforwarded_remoteaddr_route
        uri: https://example.org
        predicates:
        - XForwardedRemoteAddr=192.168.1.1/24

此路由匹配,如果X-Forwarded-For标题包含,例如,192.168.1.10.

1.5.2 自定义断言路由工厂

自定义路由断言工厂需要继承AbstractRoutePredicateFactory类,重写appy方法的逻辑。

在appy方法中可以通过 exchange.getReuest()拿到 ServerHttpRequest() 对象。从而可以求取到清求的参数、请求方式、请求头等信息。

注意命名要以RoutePredicateFactory结尾

@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config>{
    public MyRoutePredicateFactory() {
        super(MyRoutePredicateFactory.Config.class);
    }

    public List<String> shortcutFieldOrder() {
        return Arrays.asList("name");
    }

    @Override
    public Predicate<ServerWebExchange> apply(final MyRoutePredicateFactory.Config config) {
        return new GatewayPredicate() {
            public boolean test(ServerWebExchange exchange) {
                if (config.getName().equals("huozhexiao")){
                    return true;
                }else {
                    return false;
                }
            }
        };
    }
    //接受配置文件断言信息
    public static class Config {
       private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}
  • 配置

              predicates:
                - My=huozhexiao
    

1.6 过滤器工厂

在 Gateway 中, Filter 的⽣命周期只有两个: prepost

  • PRE: 这种过滤器在请求被路由调⽤之前调⽤。可利⽤这种过滤器实现身份验证、在集群中选择请求的微服 务、记录调试信息等。

  • POST:这种过滤器在路由到微服务以后执⾏。可⽤来为响应添加标准的 HTTP Header 、收集统计信息和指 标、将响应从微服务发送给客户端等。

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第3张图片

Gateway 的过滤器从作⽤范围可分为两种: GatewayFilter 与 GlobalFilter 。

  • GatewayFilter:应⽤到单个路由或者⼀个分组的路由上。

  • GlobalFilter:应⽤到所有的路由上。

1.6.1 内置局部过滤器工厂

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

过滤器工厂 作用 参数
AddRequestHeader 为原始请求添加Header Header的名称及值
AddRequestParameter 为原始请求添加请求参数 参数名称及值
AddResponseHeader 为原始响应添加Header Header的名称及值
DedupeResponseHeader 剔除响应头中重复的值 需要去重的Header名称及去重策略
Hystrix 为路由引入Hystrix的断路器保护 HystrixCommand的名称
FallbackHeaders 为fallbackUri的请求头中添加具体的异常信息 Header的名称
PrefixPath 为原始请求路径添加前缀 前缀路径
PreserveHostHeader 为请求添加一个preserveHostHeader=true的属性,路由过滤器会检查该属性以决定是否要发送原始的Host
RequestRateLimiter 用于对请求限流,限流算法为令牌桶 keyResolver、rateLimiter、statusCode、denyEmptyKey、emptyKeyStatus
RedirectTo 将原始请求重定向到指定的URL http状态码及重定向的url
RemoveHopByHopHeadersFilter 为原始请求删除IETF组织规定的一系列Header 默认就会启用,可以通过配置指定仅删除哪些Header
RemoveRequestHeader 为原始请求删除某个Header Header名称
RemoveResponseHeader 为原始响应删除某个Header Header名称
RewritePath 重写原始的请求路径 原始路径正则表达式以及重写后路径的正则表达
RewriteResponseHeader 重写原始响应中的某个Header Header名称,值的正则表达式,重写后的值
SaveSession 在转发请求之前,强制执行WebSession::save操作
secureHeaders 为原始响应添加一系列起安全作用的响应头 无,支持修改这些安全响应头的值
SetPath 修改原始的请求路径 修改后的路径
SetResponseHeader 修改原始响应中某个Header的值 Header名称,修改后的值
SetStatus 修改原始响应的状态码 HTTP 状态码,可以是数字,也可以是字符串
StripPrefix 用于截断原始请求的路径 使用数字表示要截断的路径的数量
Retry 针对不同的响应进行重试 retries、statuses、methods、series
RequestSize 设置允许接收最大请求包的大小。如果请求包大小超过设置的值,则返回 413 Payload Too Large 请求包大小,单位为字节,默认值为5M
ModifyRequestBody 在转发请求之前修改原始请求体内容 修改后的请求体内容
ModifyResponseBody 修改原始响应体的内容 修改后的响应体内容
Default 为所有路由添加过滤器 过滤器工厂名称及值

每个过滤器工厂都对应一个实现类,并且这些类的名称必须以GatewayFilterFactory结尾

1.6.2 自定义局部过滤器

继承AbstractGatewayFilterFactory

@Component
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.Config> {
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("value");
    }

    public MyGatewayFilterFactory() {
        super(MyGatewayFilterFactory.Config.class);
    }

    @Override
    public GatewayFilter apply(MyGatewayFilterFactory.Config config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                /*
                 * 1.获取name参数
                 * 2. 如果!=value不放行,反正放行
                 * */
                String name = exchange.getRequest().getQueryParams().getFirst("name");
                if (StringUtils.isNotBlank(name)){
                    if (config.getValue().equals(name)){
                        chain.filter(exchange);
                    }else {
                        exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
                        return exchange.getResponse().setComplete();
                    }
                }
                //正常请求

                return chain.filter(exchange);
            }
        };
    }

    public static class Config {
        private String value;

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }
}
  • 配置

              filters:
                 - My=huozhexiao
    

1.6.3 内置全局过滤器工厂

无需配置、可直接使用

具体使用方法看官方文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#global-filters

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第4张图片

1.6.4 自定义全局过滤器

继承GlobalFilter实现filter()方法

  • 自定义日志demo
@Component
public class LogFilter implements GlobalFilter {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        logger.info(exchange.getRequest().getPath().value());
        return chain.filter(exchange);
    }
}

Reactor Netty 访问日志

要启用Reactor Netty 访问日志,请设置-Dreactor.netty.http.server.accessLogEnabled=true.

  • 它必须是Java系统属性,而不是spring Boot属性。
  • 自定义鉴权demo
@Component
@Slf4j
public class TokenGlobalFilter implements GlobalFilter, Ordered {
    //鉴权
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("开始鉴权...");
        List<String> tokens = exchange.getRequest().getHeaders().get("token");
        if (tokens != null || tokens.size() == 0) {
            return error(exchange);
        }
        //获取token
        String token = tokens.get(0);
        log.info("token:{}",token);
        //token判断
        return chain.filter(exchange);
    }

    private Mono<Void> error(ServerWebExchange exchange) {
        // 浏览器没有携带token
        // 获取响应对象
        ServerHttpResponse response = exchange.getResponse();
        // 设置响应状态码
        response.setStatusCode(HttpStatus.resolve(403));
        // 设置返回格式
        response.getHeaders().set("ContentType", "application/json;charset=utf-8");
        // 设置返回的内容
        JsonResult result = new JsonResult(true,"200",null,"用户未登陆...");
        String str = JSONArray.toJSONString(result);
        DataBuffer data = response.bufferFactory().wrap(str.getBytes(StandardCharsets.UTF_8));
        log.info("⽤户未携带token,{}", str);
        return response.writeWith(Mono.just(data));
    }

    //优先级
    @Override
    public int getOrder() {
        return 1;
    }
}

1.7 Gateway跨域配置

通过yml配置

spring:
   cloud:
   	 gateway:
	   globalcors:
		 cors-configurations:
		 	'[/**]:		//允许跨域访问访问的资源
			 allowedOrigins: "*"  //允许跨域访问的来源
             allowedMethods: 	//允许跨域请求的访问
             	- GET
			    - POST
			    - DELETE
			    - PUT
			    -OPTION

通过配置类配置

@configuration
public class corsconfig {
	@Bean
	public corswebFilter corsFilter() {
			corsconfiguration config = new corsconfiguration();
        	config.addAllowedMethod("*");
			config.addAllowedorigin("*");
            config.addAllowedHeader("*");
        	//允许访问的资源	
			UrlBasedCorsConfigurationSource source = new UrlBasedcorsconfigurationsource(new PathPatternParser());
        	source.registerCorsconfiguration("/**", config);
			return new corsWebFilter(source);
    }
}

1.8 Gataway整合sentinel流控降级

网关层限流可针对不同路由,也可针对业务接口进行限流,根据接口特征进行限流

官方文档:https://sentinelguard.io/zh-cn/docs/api-gateway-flow-control.html

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第5张图片

① 引入依赖

<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-alibaba-sentinel-gatewayartifactId>
dependency>
<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
dependency>

②添加sentinel控制台配置

spring:
  application:
    name: huozhexiao-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.198.129:4399
        password: nacos
        username: nacos
    gateway:
      routes: #路由规则列表,指定当请求满足条件转到对应服务
        - id: order-router   # 路由唯一标识   
          uri: lb://order-service #需要转发的地址 lb:负载均衡
          # 配置断言,用于路由规则匹配
          predicates:
            - Path=/order/**
    sentinel:
      transport:
        dashboard: localhost:1234

整合流控降级详细配置

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第6张图片

API分组:可定义一组api进行流控

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第7张图片

降级规则

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第8张图片

使用自定义异常进行降级处理

@PostConstruct
public void init(){
    BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
        @Override
        public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
            //自定义异常处理      
            return ServerResponse.status(HttpStatus.OK)
                    .contentType(MediaType.APPLICATION_JSON)
                    .body(BodyInserters.fromValue(new JsonResult(true,HttpStatus.TOO_MANY_REQUESTS.toString(),null,"限流了")));
        }
    };
    //设置自定义异常
    GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}

2 SkyWalking

在庞大的微服务体系中,某个服务出现错误,会很难解决,SkyWalking链路追踪可以帮助我们理清整个服务调用链路,解决问题

  • 中文文档:https://skyapm.github.io/document-cn-translation-of-skywalking/
  • 官网:https://skywalking.apache.org/

2.1 什么是SkyWalking

skywalking是一个国产开源框架,2015年由吴晟开源,2017年加入Apache孵化器。skywalking是分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。它是一款优秀的APM(Application Perfomance Management)工具,包括了分布式追踪、性能指标分析、应用和服务依赖分析等。

  • 市场上的链路追踪框架对比

    链路追踪框架对比

    1. zipkin:zipkin是Twitter开源的调用链分析工具,目前基于springcloud sleuth得到了广泛的使用,特点是轻量,使用部署简单。

    2. Pinpoint:Pinpoint是韩国人开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,U功能强大,接入端无代码侵入

    3. SkyWlaking:SkyWlaking是本土开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI功能较强,接入端无代码侵入。目前已加入Apache孵化器。

    4. CAT是大众点评开源的基于编码和配置的调用链分析,应用监控分析,日志采集,监控报警等一系列的监控平台工具。

  • SkyWalking主要功能特性

    1.多种监控手段,可以通过语言探针和service mesh获得监控的数据

    2.支持多种语言自动探针,包括Java、.Net Core和Node JS等

    3.轻量高效,无需大数据平台和大量的服务器资源

    4.模块化、UI、存储、集群管理都有多种机制可选

    5.支持告警

    6.优秀的可视化解决方案

2.2 SkyWalking服务端搭建

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第9张图片

  • Skywalking agent和业务系统绑定在一起,负责收集各种监控数据
  • Skywalking oapservice是负责处理监控数据的,比如接受Skywalking agent的监控数据,并存储在数据库中;接受Sky walking webapp的前端请求,从数据库查询数据,并返回数据给前端。
  • Skywalking oapservice通常以集群的形式存在。
  • Skywalking webapp,前端界面,用于展示数据。
  • 用于存储监控数据的数据库,比如mysql、elasticsearch等。

2.2.1 下载SkyWalking

  • 下载地址:https://skywalking.apache.org/downloads/

选择版本下载

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第10张图片

  • 解压…

2.2.2 目录结构

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第11张图片

新版本agent目录独立出去了,需要自己下载

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第12张图片

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第13张图片

  • 启动bin/startup.sh会同时启动(oapservice和webapp)

    • 在webapp/webapp.yml修改webapp端口号,默认为8080

    • 在conf/application.yml修改oapservice端口, 服务启动后会暴露11800和12800端口,分别为收集监控数据的端口11800和接收前端请求的端口12800

2.2.3 接入微服务

启动微服务时添加配置

更多配置见:https://skywalking.apache.org/docs/skywalking-java/next/en/setup/service-agent/java-agent/configurations/

-javaagent:E:\skywalking\apache-skywalking-apm-bin\skywalking-agent\skywalking-agent.jar -DSW_AGENT_NAME=stock-service   #服务名
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800  #aollector连接地址

SpringCloudAlibaba下篇(GateWay,Skywalking)(超级无敌认真好用,万字收藏篇!!!!)_第14张图片

2.2.4 使用mysql持久化

SkyWalking默认使用h2进行持久化

  • 修改conf/application.yml文件

    • 选择mysql
    storage:
      selector: ${SW_STORAGE:mysql}
    
    • 配置mysql
      mysql:
        properties:
          jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://192.168.198.129:3306/swtest?rewriteBatchedStatements=true"}
          dataSource.user: ${SW_DATA_SOURCE_USER:root}
          dataSource.password: ${SW_DATA_SOURCE_PASSWORD:root}
          dataSource.cachePrepStmts: ${SW_DATA_SOURCE_CACHE_PREP_STMTS:true}
          dataSource.prepStmtCacheSize: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_SIZE:250}
          dataSource.prepStmtCacheSqlLimit: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_LIMIT:2048}
          dataSource.useServerPrepStmts: ${SW_DATA_SOURCE_USE_SERVER_PREP_STMTS:true}
        metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:5000}
        maxSizeOfBatchSql: ${SW_STORAGE_MAX_SIZE_OF_BATCH_SQL:2000}
        asyncBatchPersistentPoolSize: ${SW_STORAGE_ASYNC_BATCH_PERSISTENT_POOL_SIZE:4}
    
    • 启动skywalking会自动建表

    • 报错:Failed to get driver instance for jdbcUrl=jdbc:mysql://192.168.198.129:3306/swtest?rewriteBatchedStatements=true

      缺少mysql驱动,oap-libs中导入mysql驱动包即可

2.2.5 自定义链路追踪

如果我们希望对项目中的业务方法,实现链路追踪,方便我们排查问题,可以使用如下的代码

  • 引入依赖
     
        <dependency>
            <groupId>org.apache.skywalkinggroupId>
            <artifactId>apm-toolkit-traceartifactId>
            <version>8.12.0version>
        dependency>
  • 加入@Trace注解
    @Trace
    public Order create(Order order) {
        orderMapper.add(order);
        //扣减库存能否成功
        stockFegin.reduct(order.getProduct_id());
        int a = 1 / 0;
        return order;
    }
  • 加入@Tags@Tag

增加其他额外信息例如参数和返回信息

   @Trace
    @Tags({@Tag(key = "param",value = "arg[0]"),
            @Tag(key = "order",value = "returnObj")})
    public Order create(Order order) {
        orderMapper.add(order);

        //扣减库存能否成功
        stockFegin.reduct(order.getProduct_id());
        int a = 1 / 0;
        return order;

    }

2.3 告警

疑似出现异常或者出现异常进行告警

告警规则

SkyWalking 的发行版都会默认提供config/alarm-settings.yml文件,里面预先定义了一些常用的告警规则。如下;

  1. 过去3分钟内服务平均响应时间超过1秒。
  2. 过去2分钟服务成功率低于80%。
  3. 过去3分钟内服务响应时间超过1s 的百分比
  4. 服务实例在过去2分钟内平均响应时间超过1s,并且实例名称与正则表达式匹配。
  5. 过去2分钟内端点平均响应时间超过1秒。
  6. 过去2分钟内数据库访问平均响应时间超过1秒。7.过去2分钟内端点关系平均响应时间超过1秒。

告警规则配置项的说明

  • Rule name:规则名称,也是在告警信息中显示的唯一名称。必须以_rule结尾,前缀可自定义
  • Metrics name:度量名称,取值为oal脚本中的度量名,目前只支持long、double和int类型。详见Official OAL script
  • Include names:该规则作用于哪些实体名称,比如服务名,终端名(可选,默认为全部)
  • Exclude names:该规则作不用于哪些实体名称,比如服务名,终端名(可选,默认为空)
  • Threshold:阈值
  • OP: 操作符,目前支持 >、<、=
  • Period:多久告警规则需要被核实一下。这是一个时间窗口,与后端部署环境时间相匹配
  • Count:在一个Period窗口中,如果values超过Threshold值(按op),达到Count值,需要发送警报
  • Silence period:在时间N中触发报警后,在TN -> TN + period这个阶段不告警。 默认情况下,它和Period一样,这意味着相同的告警(在同一个Metrics name拥有相同的Id)在同一个Period内只会触发一次
  • message:告警消息

  • 学习来自于b站图灵

你可能感兴趣的:(JAVA小记,gateway,skywalking,java,微服务)