中间件知识点-微服务中间件(其他)二

Ribbon

(客户端负载均衡,微服务一般不用Ribbon做负载均衡了,因为ribbon依赖于Netflix,Netflix闭源了,目前比较多用的是Feign。)
1.ribbon是什么?
Spring Cloud Ribbon是基于Netflix Ribbon 实现的一套客户端的负载均衡工具,Ribbon客户端组件提供一系列的完善的配置,如超时,重试等。通过Load Balancer获取到服务提供的所有机器实例,Ribbon会自动基于某种规则(轮询,随机)去调用这些服务。Ribbon也可以实现我们自己的负载均衡算法。
2.负载均衡
集中式负载均衡:有硬件的(比如 F5),也有软件的(比如 Nginx)
客户端负载均衡:客户端根据自己的请求情况做负载均衡,Ribbon 就属于客户端自己做负载均衡。
3.负载均衡算法
最小连接数(用到比较多的算法,其他的如随机、轮询、加权轮询、地址hash用的没那么多),即使请求均衡了,压力不一定会均衡,最小连接数法就是根据服务器的情况,比如请求积压数等参数,将请求分配到当前压力最小的服务器上。
4.ribbon可以自定义负载均衡策略

LoadBalancer

Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客户端负载均衡器, 用来替代Ribbon。
Spring官方提供了两种客户端都可以使用loadbalancer:RestTemplate、WebClient

OpenFeign

1.远程过程调用(rpc)和http请求区别
a.远程方法调用:consumer 直接调用接口方法调用 provider,而不需要通过常规的 HttpClient 构造请求再解析返回数据。
即一般http调用,需要传get post url params这些。而rpc只需引入远程接口,然后通过orderservice.method()方式调用。
b.OpenFeign rpc架构底层最终还是通过发送http请求来传输数据。
OpenFeign是rpc架构。

2.什么是Feign?(一个通过http方式传输rpc远程调用参数的客户端)
Feign是Netflix开发的声明式、模板化的HTTP客户端,Feign可帮助我们更加便捷、优雅地调用HTTP API。
Feign可以做到使用 HTTP 请求远程服务时就像调用本地方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是个 HTTP 请求。它像 Dubbo 一样,consumer 直接调用接口方法调用 provider,而不需要通过常规的 Http Client 构造请求再解析返回数据。它解决了让开发者调用远程接口就跟调用本地方法一样,无需关注与远程的交互细节,更无需关注分布式环境开发。

3.OpenFeign与Feign的关系?(OpenFeign是Feign的升级版)
Spring Cloud openfeign对Feign进行了增强,使其支持Spring MVC注解,另外还整合了Ribbon和Eureka,从而使得Feign的使用更加方便。

4.OpenFeign的扩展点
a.日志配置
(方便查看请求日志信息,可对日志级别进行配置)
b.契约配置(用于支持Feign原生注解,如果要使用原始注解的话)
比如项目是一个spring项目而不是springmvc项目,所以不能用springmvc注解,此时只能
用feign原生注解。为了能够使用原生注解,可以通过配置契约来改变这个配置,默认的是 SpringMvcContract。
c.通过拦截器实现参数传递
使用场景

  1. 统一添加 header 信息;
  2. 对 body 中的信息做修改或替换;
    d.超时时间配置
    e.客户端组件配置
    Feign 中默认使用 JDK 原生的 URLConnection 发送 HTTP 请求,我们可以集成别的组
    件来替换掉 URLConnection,比如 Apache HttpClient,OkHttp。
    f.GZIP 压缩配置
    开启压缩可以有效节约网络资源,提升接口性能,我们可以配置 GZIP 来压缩数据
    只有当 Feign 的 Http Client 不是 okhttp3 的时候,压缩才会生效
    g.编码器解码器配置
    Feign 中提供了自定义的编码解码器设置,同时也提供了多种编码器的实现,比如Gson、Jaxb、Jackson。

5.OpenFeign与负载均衡器的关系?
Feign的底层用的是Ribbon(所以Feign可以进行负载均衡)

Sentinel

(流量治理组件)(生产环境要么使用企业级要么在开源基础上进行改造)(整个springcloud重要的两个中间件是Sentinel Nacos)
分布式系统遇到的问题
服务雪崩效应:因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程,就叫服务雪崩效应
导致服务不可用的原因: 程序Bug,大流量请求,硬件故障,缓存击穿
1.大流量请求:在秒杀和大促开始前,如果准备不充分,瞬间大量请求会造成服务提供者的不可用。
2.硬件故障:可能为硬件损坏造成的服务器主机宕机, 网络硬件故障造成的服务提供者的不可访问。
3.缓存击穿:一般发生在缓存应用重启, 缓存失效时高并发,所有缓存被清空时,以及短时间内大量缓存失效时。大量的缓存不命中, 使请求直击后端,造成服务提供者超负荷运行,引起服务不可用。

解决方案:
a.超时机制:即客户端增加超时机制,避免一直占用资源
b.服务限流(资源隔离):即每个服务都分配有一定数量的单独的线程(Hystrix用到这种方案)。
c.服务熔断
依赖服务不稳定或网络抖动时暂时关闭当前服务,就叫服务熔断。当依赖的服务有大量超时时,在让新的请求去访问根本没有意义,只会无畏的消耗现有资源。
d.服务降级(熔断后返回缺省值)
所谓降级,就是当某个服务熔断之后,服务将不再被调用,此时客户端可以自己准备一个本地的fallback(回退)回调,返回一个缺省值。 例如:(备用接口/缓存/mock数据) 。这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合的业务场景。

Sentinel 是什么(流量治理组件)
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。

Sentinel工作原理
A.利用责任链过滤器链对流量进行统一管理,进行管理控制。具体的是Sentinel使用Slot(包括各种Slot,比如FlowSlot)作为流量入口,做一些逻辑操作。
B.Sentinel工作主流程
(每次资源调用都会创建一个 Entry 对象,创建Entry对象的时候又会创建插槽,然后执行插槽)
在 Sentinel 里面,所有的资源都对应一个资源名称(resourceName),每次资源调用都会创建一个 Entry 对象。Entry 可以通过对主流框架的适配自动创建,也可以通过注解的方式或调用 SphU API 显式创建。Entry 创建的时候,同时也会创建一系列功能插槽(slot chain),这些插槽有不同的职责,例如:
1.NodeSelectorSlot 负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来
限流降级;
2.ClusterBuilderSlot 则用于存储资源的统计信息以及调用者信息,例如该资源的 RT, QPS, thread count 等等,
这些信息将用作为多维度限流,降级的依据;
3.StatisticSlot 则用于记录、统计不同纬度的 runtime 指标监控信息;
4.FlowSlot 则用于根据预设的限流规则以及前面 slot 统计的状态,来进行流量控制;
5.AuthoritySlot 则根据配置的黑白名单和调用来源信息,来做黑白名单控制;
6.DegradeSlot 则通过统计信息以及预设的规则,来做熔断降级;
7.SystemSlot 则通过系统的状态,例如 load1 等,来控制总的入口流量;

创建的slot chain具体是怎么调用,怎么工作的?
创建的插槽链(slot chain)是在创建Entry对象时建立的,它是一系列功能插槽的集合,用于对请求进行处理和控制。在创建Entry时,将按照配置的插槽链顺序依次执行每个插槽。
具体工作流程如下:
1.创建Entry对象:
当系统中有请求访问某个资源时,会创建对应的Entry对象。
Entry对象包含了对该资源的访问统计、流量控制、降级等管理。

2.选择/创建插槽链:
根据配置选择要使用的插槽链,可以是默认的插槽链或者用户自定义的插槽链。
插槽链定义了请求在进入该链条时要依次经过的插槽。

3.依次执行插槽:
请求进入插槽链后,会依次经过每个插槽。
每个插槽都有机会对请求进行处理和控制,可以决定请求是否通过以及如何进行后续的处理。

4.处理请求:
每个插槽都会根据自身的逻辑对请求进行处理,可能包括流量控制、降级、系统保护等操作。
如果某个插槽决定拒绝请求或者触发了相应的控制策略,后续插槽将不会执行,请求将被拦截或者进行相应的处理。

5.返回结果:
请求经过所有插槽的处理后,最终会得到一个处理结果。
结果可能是正常通过,也可能是被拦截或者进行了降级处理。

通过插槽链的构建和管理,Sentinel能够实现对资源访问的统计、流量控制、降级等一系列功能的管理和控制,从而保障系统的稳定性和可靠性。

限流算法
1.滑动时间窗口算法
可以减少计数器算法的误差
快速失败使用的是sentinel自己实现的滑动时间窗口算法
滑动时间窗口,又称rolling window。为了解决计数器法统计精度太低的问题,引入了滑动窗口算法。下面这张图,很好地解释了滑动窗口算法:
在这里插入图片描述在上图中,整个红色的矩形框表示一个时间窗口,在我们的例子中,一个时间窗口就是一分钟。然后我们将时间窗口进行划分,比如图中,我们就将滑动窗口划成了6格,所以每格代表的是10秒钟。每过10秒钟,我们的时间窗口就会往右滑动一格。每一个格子都有自己独立的计数器counter,比如当一个请求 在0:35秒的时候到达,那么0:30~0:39对应的counter就会加1。
计数器算法其实就是滑动窗口算法。只是它没有对时间窗口做进一步地划分,所以只有1格。
由此可见,当滑动窗口的格子划分的越多,那么滑动窗口的滚动就越平滑,限流的统计就会越精确。

总结:
a.这里的滑动时间窗口算法是每个格子记录了总的次数,而sentinel每个格子记录的是当前时间段的次数。
b.滑动时间窗口算法相对计数器算法更精确,但不能100%精确。格子越小,精度越高。

1 /**
2 * 滑动时间窗口限流实现
3 * 假设某个服务最多只能每秒钟处理100个请求,我们可以设置一个1秒钟的滑动时间窗口,
4 * 窗口中有10个格子,每个格子100毫秒,每100毫秒移动一次,每次移动都需要记录当前服务请
求的次数
5 */
6 public class SlidingTimeWindow {
7 //服务访问次数,可以放在Redis中,实现分布式系统的访问计数
8 Long counter = 0L;
9 //使用LinkedList来记录滑动窗口的10个格子。
10 LinkedList slots = new LinkedList();
11
12 public static void main(String[] args) throws InterruptedException {
13 SlidingTimeWindow timeWindow = new SlidingTimeWindow();
14
15 new Thread(new Runnable() {
16 @Override
17 public void run() {
18 try {
19 timeWindow.doCheck();20 } catch (InterruptedException e) {
21 e.printStackTrace();
22 }
23 }
24 }).start();
25
26 while (true){
27 //TODO 判断限流标记
28 timeWindow.counter++;
29 Thread.sleep(new Random().nextInt(15));
30 }
31 }
32
33 private void doCheck() throws InterruptedException {
34 while (true) {
35 slots.addLast(counter);
36 if (slots.size() > 10) {
37 slots.removeFirst();
38 }
39 //比较最后一个和第一个,两者相差100以上就限流
40 if ((slots.peekLast() ‐ slots.peekFirst()) > 100) {
41 System.out.println(“限流了。。”);
42 //TODO 修改限流标记为true
43 }else {
44 //TODO 修改限流标记为false
45 }
46
47 Thread.sleep(100);
48 }
49 }
50 }

2.令牌桶算法
WarmUp使用的是令牌桶算法
3.漏桶算法
排队等待(匀速等待)使用的是漏桶算法

Seata

分布式事务简介
1.本地事务
只操作单一的数据库,本地事务的ACID特性是数据库直接提供支持。
2.分布式事务
需要操作的资源位于多个资源服务器、多个数据库上,而应用需要保证对于多个资源服务器的数据操作,要么全部成功,要么全部失败。分布式事务就是为了保证不同资源服务器的数据一
致性。
应用场景:1) 跨库事务 2) 分库分表 3) 微服务架构

分布式事务及seata看"方案实践/架构-分布式架构"

Gateway

API网关是随着微服务概念兴起的一种架构模式,它是运行于外部请求与内部服务之间的一个流量入口,为微服务架构的系统提供简单、有效且统一的API路由管理,作为系统的统一入口,提供内部服务的路由中转,给客户端提供统一的服务。可以基于Filter 的方式实现一些和业务没有耦合的公用逻辑,主要功能包含认证、鉴权、路由转发、安全策略、防刷、流量控制、监控日志等。

在外部请求和网关集群间可以加入负载均衡器。在网关和微服务之间也可以加入负载均衡器,从下面可以看出:
uri: lb://mall‐order #lb 整合负载均衡器ribbon/loadbalancer

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

spring cloud gateway 核心概念
1.路由(route)
路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。
2.断言(predicates)
看Http request是否和我们定义的信息是否匹配,如果断言为真,即匹配,则走路由。
3.过滤器(Filter)
SpringCloud Gateway中的filter分为Gateway Filter和Global Filter。Filter可以对请求和响应进行处理。如果请求与网关程序定义的路由匹配,则该请求就会被发送到网关 Web 处理程序,此时处理程序运行特定的请求过滤器链。
spring.cloud.gateway.routes[14].id=cms
spring.cloud.gateway.routes[14].uri=lb://cms
spring.cloud.gateway.routes[14].predicates[0]=Path=/dc/cms/**
spring.cloud.gateway.routes[14].filters[0]=StripPrefix=1 //指定的过滤器类型和其参数

spring.cloud.gateway.routes[14].filters[0]=StripPrefix=1表达的是什么意思?
StripPrefix: 是Spring Cloud Gateway内置的过滤器之一,用于去除请求路径的前缀。
1: 是指定要去除的前缀数目。在这里,设置为1表示去除请求路径的第一个路径段(即第一个斜杠后的路径段)。
比如当发送到网关的请求路径是 /service1/path/to/resource 时,经过该路由配置后,网关会将请求转发给 http://localhost:8081/path/to/resource,去除了路径的第一个段 /service1。

网关过滤器需要配置、全局过滤器不需要配置。
网关过滤器是作用在特定路由上,而全局过滤器是作用在所有路由上。
路由断言工厂可配置路径、header断言
网关过滤器工厂( GatewayFilter Factories)可以配置:添加请求头、请求参数、自定义过滤器工厂。网关过滤器需要通过spring.cloud.routes.filters配置在具体的路由下,只作用在当前特定路由上,也可以通过配置spring.cloud.default-filters让它作用于全局路由上。
全局过滤器(Global Filters),不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain能够识别的过滤器。
gateway自带了一些网关过滤器和全局过滤器。也可以进行自定义网关和全局过滤器。

Spring Cloud Gateway 的工作原理跟 Zuul 的差不多,最大的区别就是 Gateway 的 Filter 只有 pre和 post 两种。

Gateway跨域配置(CORS Configuration)
(浏览器出于保护机制,会阻止一个域的js和另一个域的js进行交互,所以需要进行跨域配置)
1.在前端领域中,跨域是指浏览器允许向服务器发送跨域请求,从而克服Ajax只能同源使用的限制。
同源策略(Same Orgin Policy)是一种约定,它是浏览器核心也最基本的安全功能,它会阻止一个域的js脚本和另外一个域的内容进行交互,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源(即在同一个域)就是两个页面具有相同的协议(protocol)、主机(host)和端口号(port)。
2.只要网络协议,ip 地址,端口中任何一个不相同就是跨域请求。
3.实现跨域法是有多种,分cors,jsonp,代理服务器等使用代理服务器解决跨域。因为代理服务器不是浏览器和后端交互,而是通过http请求服务器,不会出现跨域问题
实际上最终都是是由后端来解决跨域
4.如何解决gateway跨域问题?
(浏览器和服务端的跨域)
a.通过yml配置的方式
b.通过java配置的方式
5.跨域既然是由浏览器控制的,那为什么java后端服务可以通过配置来支持跨域?
(浏览器和浏览器之间、浏览器和服务端之间都存在跨域问题,浏览器间的跨域无法解决,浏览器和服务端的跨域可以解决。)
a.跨域问题是由浏览器的同源策略引起的,同源策略是浏览器的一种安全策略,用于限制一个源(协议 + 域名 + 端口)的文档或脚本如何能与另一个源的资源进行交互。而Java后端服务可以通过配置来支持跨域,是因为Java后端服务并不受同源策略的限制,Java后端服务可以通过设置响应头来告诉浏览器是否允许跨域请求。常见的设置响应头的方式有两种:一种是实现WebMvcConfigurer接口,重写addCorsMappings()方法,另一种是在方法上使用注解@CrossOrigin。这两种方式都是通过设置响应头来告诉浏览器是否允许跨域请求的。
b.是否浏览器和浏览器存在跨域,浏览器和服务端也存在跨域?
是的,浏览器和浏览器之间、浏览器和服务端之间都存在跨域问题。
浏览器和浏览器之间的跨域问题,是指当一个网页中的脚本试图访问另一个网页中的资源时,由于浏览器的同源策略,这种访问会被禁止。同源策略是浏览器的一种安全策略,它要求网页只能访问与其来源相同的资源,而不能访问其他来源的资源。同源是指协议、域名、端口号都相同。
浏览器和服务端之间的跨域问题,是指当一个网页中的脚本试图向不同源的服务器发送请求时,由于同源策略的限制,这种请求会被浏览器拒绝。为了解决这个问题,可以使用跨域资源共享(CORS)技术,或者使用JSONP等其他技术。
c.浏览器和浏览器之间、浏览器和服务端之间都存在跨域问题。浏览器和浏览器之间的跨域无法解决,浏览器和服务端之间接口的跨域可以通过配置解决。

Gateway整合sentinel限流
从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:
route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId
自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组

webflux对比webmvc流程
a.webmvc的流程:
DispatcherServlet
HandlerMapping 路由匹配
HandlerAdapter适配器 ( servlet controller @RequestMapping)
b.webflux的流程:
DispatcherHandler
HandlerMapping 路由匹配
找到WebHandler(其由对应的HandlerAdapter处理)
HandlerAdapter 适配器RoutePredicateHandlerMapping

Flux、Mono和webflux的关系
Flux 和 Mono 是 Reactor 框架提供的两种用于处理响应式编程的数据流的类。其中,Flux 用于处理包含多个元素的数据流,而 Mono 则用于处理仅包含单个元素的数据流。
WebFlux 是 Spring Framework 5.0 中引入的一个新的 web 框架,它使用了基于 Reactor 的 Flux 和 Mono 来处理响应式编程的请求和响应。WebFlux 提供了一种非阻塞的方式来处理高吞吐量的 web 请求,并可以在同一线程上同时处理多个请求。

Flux和Mono的区别?
Mono它只发送一个值,然后发送完成信号。Flux它可以发出 0 个或多个值,onnnext()请求可能是无限值,然后以完成或错误信号终止。
Mono有点类似 Java Optional类,因为它包含 0 或 1 个值;Flux更像List,因为它可以有 N 个值。

gateway、springmvc、webflux请求流程的区别?
a.webflux请求流程包含了:获取handlerMapping、获取handlerAdapter、handleResult
b.而gateway中请求数据的流程只包含:获取handlerMapping、获取handlerAdapter。而没有handleResult结果处理的流程。因为gateway结果是下个微服务返回的,而不是gateway自己处理的。
从下面可以看出handlerAdapter处理完后会返回一个empty空值。
这样的话,就不会执行.flatMap(result -> handleResult(exchange, result));这句代码,所以我们上面说
了gateway有handleResult结果处理的流程。
c.springmvc/webmvc请求流程和webflux流程差不多,只是处理的类不同,其也包含了:获取
handlerMapping、获取handlerAdapter,handleResult。

webflux:Flux,Mono其实和Rxjava差不多,都是响应式编程。

webflux和rxjava的区别?
RxJava 2.0 和 Reactor 基于 ReactiveX 项目。而 Spring WebFlux 在内部使用 Reactor。
ReactiveX结合了观察者模式、迭代器模式和函数式编程的最佳思想。它扩展了观察者模式以支持数据和/或事件序列,并添加允许您以声明方式将序列组合在一起的运算符,同时抽象出对诸如低级线程、同步、线程安全、并发数据结构和非阻塞 I/O。

webmvc是基于servlet的,他使用阻塞式编程。webflux是基于reactor的,他使用的是响应式编
程,非阻塞的。

通过过滤器得到路由真正的转发地址后,然后就构建新请求,使用netty和各个微服务建立连接(而非http方式),请求数据。

gateway处理流程总结:
大体流程是先得到HandlerMapping,然后进行路由断言逻辑判断校验,然后得到WebHandler,获得WebHandler后,找到WebHandler对应的HandlerAdapter,然后HandlerAdapter会调用handle方法,handle方法中会调用webHandler.handle()方法进行处理。
在这里插入图片描述在这里插入图片描述webHandler.handle()方法会执行过滤器链的各个过滤器逻辑。其会把当前的路由过滤器和全局过滤器进行合并和排序。
在这里插入图片描述但是全局过滤器是GlobalFilter类型,而局部过滤器是GatewayFilter类型,他们是怎么合并成都是GatewayFilter类型的呢?其实主要是用到适配器模式,将所有的GlobalFilter都转成了GatewayFilter。
在这里插入图片描述GatewayFilterAdapter实现了GatewayFilter。
在这里插入图片描述通过过滤器得到路由真正的转发地址后,然后就构建新请求,使用netty和各个微服务建立连接(而非http方式),请求数据。
在这里插入图片描述每个微服务接收到网关的转发请求后,开始走springmvc的处理流程进行接口的调用处理。
在这里插入图片描述这样的话,下面的流程就懂了:
在这里插入图片描述

Skywalking

(是一个分布式全链路追踪的性能监控工具)
全链路追踪:对请求源头到底层服务的调用链路中间的所有环节进行监控。

skywalking是什么?
skywalking是分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器
(Docker、K8s、Mesos)架构而设计。

Skywalking主要功能特性
1、多种监控手段,可以通过语言探针和service mesh获得监控的数据;
2、支持多种语言自动探针,包括 Java,.NET Core 和 Node.JS;
3、轻量高效,无需大数据平台和大量的服务器资源;
4、模块化,UI、存储、集群管理都有多种机制可选;
5、支持告警;
6、优秀的可视化解决方案;

Skywalking整体架构
在这里插入图片描述在这里插入图片描述整个架构分成四部分:
1.上部分Agent(即探针,采集Tracing信息和Metrics信息,和业务系统绑定在一起):负责从应用中,收集链路信息,发送给 SkyWalking OAP 服务器;
2.下部分 SkyWalking OAP :负责接收Agent发送的Tracing数据信息,然后进行分析(Analysis Core),存储到外部存储器(Storage),最终提供查询(Query)功能;
3.右部分Storage:Tracing数据存储,目前支持ES、MySQL、ShardingSphere、TiDB、H2多种存储器,目前采用较多的是ES,主要考虑是SkyWalking开发团队自己的生产环境采用ES为主;

Tracing和Metrics的区别?Servcie Mesh是什么?
Metrics即度量指标。
Tracing即链路跟踪。
Tracing是对请求的跟踪,而Metrics是对请求的统计。
Metrics其原理是,将要监测的值记录在特定的全局变量中,然后通过HTTP的形式向外提供查询这些指标的接口,即Exporter。Prometheus会通过Exporter拉取这些数据,并存放在时序数据库中,可通过PromQL进行查询。
Service Mesh (service-to-service communication)的定位很简单也很清晰,就是用来处理服务与服务之间的通讯。
Metrics通过Servcie Mesh来传输数据,然后通过Prometheus来收集,然后通过Grafana来展示

skywalking不支持oracle数据库,所以如果itps要用的话,需额外搭建mysql。skywalking默认存在内存。skywalking可以存在mysql、elasticsearch。
SkyWalking支持三种探针:
●Agent – 基于ByteBuddy字节码增强技术实现,通过jvm的agent参数加载,并在程序启动时拦截指定的方法来收集数据。(bytebuddy对javassist进行了封装,比javassist简便,javassist比asm更强大,但是性能没有asm高,那么他们的区别是啥?下面会有讲到)
●SDK – 程序中显式调用SkyWalking提供的SDK来收集数据,对应用有侵入。
●Service Mesh – 通过Service mesh的网络代理来收集数据。
Agent只能对中间件比如dubbo/feign进行增强,他会对这些中间件已有的固定的方法
进行插装,也就是说增强的方法已经是固定了的,然后进行搜集日志,把日志搜集到
skywalking oap中。但是对业务代码不行,因为他不知道我们业务代码有哪些方法,对
于业务代码需要使用到SDK进行增强。

skywalking agent原理
a.Java Agent比Aop牛逼,Aop会对项目代码有侵入性。而Agent没有,只要在jar指令中指定agent jar包即可,是直接操作字节码。
b.skywaking就是利用bytebuddy实现的。
c.Instrumentaion、javassist、bytebuddy都是java agent技术
总结:从上面可以看出
1.Instrumentaion、javassist、bytebuddy都是java agent技术。aop不是。
2.skywaking就是利用bytebuddy进行字节码增强的
3.bytebuddy基于javassist
4.字节码增强技术包含了asm和javassist/bytebuddy,即可以使用asm/javassist来实现aop
5.ASM虽然可以达到修改字节码的效果,但是代码实现上更偏底层,是一个个虚拟机指令的组合,不好理解、记忆,和Java语言的编程习惯有较大差距。
利用Javassist实现字节码增强时,可以无须关注字节码刻板的结构,其优点就在于编程简单。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构或者动态生成类。
ASM是一种基于事件的、低级别的字节码操作框架,它通过使用Visitor设计模式,可以直接操作
字节码文件。而Javassist是一种基于反射的高级别字节码操作框架,它通过封装了Java字节码文件的API,提供了一组高级别的API来操作字节码。
由于ASM是基于低级别的字节码操作,其性能比Javassist更高,可以更加高效地操作字节码。

ASM与JAVASSIST有什么区别 - PingCode
总结:总的来说javassist比asm使用更加简便,但性能没有asm高,因为asm是直接操作字节码
的,而javassist是基于反射机制的,不直接操作字节码。

AspectJ与ASM与Javaassist
AspectJ的缺点是,由于其基于规则,所以其切入点相对固定,对于字节码文件的操作自由度以及开发的掌控度就大打折扣。还有就是我们要实现的是对所有方法进行插桩,所以代码注入后的性能也是我们需要关注的一个重要的点,我们希望只插入我们想插入的代码,而AspectJ会额外生成一些包装代码,对性能以及包大小有一定影响。
总结:也就是说aspectj会额外生成一些代码,而asm和javassist不会额外生成代码。asm是直接操作字节码。而javassist利用反射机制来间接插入字节码,不直接操作字节码文件。

6.静态代理:指代理类文件需要事先存在
程序运行前就已经存在代理类的字节码文件,代理类和原始类的关系在运行前就已经确定
缺点:不灵活,每一个需要被代理的目标类,都需要实现一个代理类,增加类、增加方法都需要对代理类代码进行修改

7.动态代理实现方式包含jdk动态代理(即javaProxy)和cglib
8.(利用反射机制)动态代理解决了静态代理的问题,程序运行期间通过JVM反射等机制动态生成代理类,代理类和目标类的关系是运行时才确定的
9.(实现类必须实现接口)Java中的动态代理,需要自定义实现一个InvocationHandler类,在其invoke方法中原有逻辑进行增强。
缺点:实现类AopDemoServiceImpl必须实现接口,Java中的动态代理通过传入的接口来反射生成一个新的类,在新的类中调用InvocationHandler.invoke对方法进行代理

10.CGLIB(当某个类没有实现某个接口时用到,需要创建一个实现MethodInterceptor接口的拦截类)
当某个类没有实现某个接口时,可以通过CGLIB来创建一个继承实现类的子类,用Asm库动态修改子类的代码来实现AOP效果
缺点:不能对final修饰的类或方法进行增强

在这里插入图片描述SkyWalking中三个概念
服务(Service) :表示对请求提供相同行为的一系列或一组工作负载,在使用Agent时,可以定义服务的名字;
服务实例(Service Instance) :上述的一组工作负载中的每一个工作负载称为一个实例, 一个服务实例实际就是操作系统上的一个真实进程;
端点(Endpoint) :对于特定服务所接收的请求路径, 如HTTP的URI路径和gRPC服务的类名 + 方法签名;
从下面可以看出,服务就是微服务名,服务实例就是微服务实例,端点就是一个方法/接口什么的。

SkyWalking使用
1.SkyWalking Agent集成
2.Skywalking集成日志框架
(包括Skywalking通过grpc上报日志)
3.Skywalking告警通知
Skywalking持久化追踪数据
(基于mysql/elasticsearch)
4.自定义SkyWalking链路追踪
5.Skywalking集群部署(oap服务高可用)
Skywalking集群是将skywalking oap作为一个服务注册到nacos上,只要skywalking oap服务没有全部宕机,保证有一个skywalking oap在运行,就能进行追踪。
搭建一个skywalking oap集群需要:
(1)至少一个Nacos(也可以是nacos集群)
(2)至少一个ElasticSearch(也可以是es集群)
(3)至少2个skywalking oap服务;
(4)至少1个UI(UI也可以集群多个,用Nginx代理统一入口)

Spring Security OAuth2微服务安全

OAuth2.0
OAuth2.0介绍
OAuth(Open Authorization)是一个关于授权(authorization)的开放网络标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容。OAuth在全世界得到广泛应用,目前的版本是2.0版。

1.2 基本概念
(1)Third­party application:第三方应用程序,又称"客户端"(client),即例子中的"云冲印"。
(2)HTTP service:HTTP服务提供商,简称"服务提供商",即例子中的Google。
(3)Resource Owner:资源所有者,又称"用户"(user)。
(4)User Agent:用户代理,比如浏览器。
(5)Authorization server:授权服务器,即服务提供商专门用来处理认证授权的服务器。
(6)Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与授权服务器,可以是同一台服务器,也可以是不同的服务器。
OAuth的作用就是让"客户端"安全可控地获取"用户"的授权,与"服务提供商"进行交互。

优缺点
1.优点:
更安全,客户端不接触用户密码,服务器端更易集中保护
广泛传播并被持续采用
短寿命和封装的token
资源服务器和授权服务器解耦
集中式授权,简化客户端
HTTP/JSON友好,易于请求和传递token
考虑多种客户端架构场景
客户可以具有不同的信任级别
2.缺点:
协议框架太宽泛,造成各种实现的兼容性和互操作性差
不是一个认证协议,本身并不能告诉你任何用户信息。

所以oauth2.0只是一个授权框架,而不是一个认证+授权框架。本身并不能告诉你任何用户信息?
意思是说oauth2.0授权框架协议,本身不存储用户的信息,它只是一个协议。要获取信息需要通过code获取token,再通过token去服务提供商获取用户认证信息。

OAuth2的设计思路
OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(authorization layer)。“客户端"不能直接登录"服务提供商”,只能登录授权层,以此将用户与客户端区分开来。"客户端"登录授权层所用的令牌(token),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期,"客户端"登录授权层以后,"服务提供商"根据令牌的权限范围和有效期,向"客户端"开放用户储存的资料。
OAuth 2.0的运行流程如下图,摘自RFC 6749:
在这里插入图片描述(A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。
(C)客户端使用上一步获得的授权,向授权服务器申请令牌。
(D)授权服务器对客户端进行认证以后,确认无误,同意发放令牌。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源。
令牌(token)与密码(password)的作用是一样的,都可以进入系统,但是有三点差异。
(1)令牌是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。
(2)令牌可以被数据所有者撤销,会立即失效。密码一般不允许被他人撤销。
(3)令牌有权限范围(scope)。对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限。
上面这些设计,保证了令牌既可以让第三方应用获得权限,同时又随时可控,不会危及系统安全。这就是 OAuth 2.0 的优点。

客户端授权模式
1.客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0 对于如何颁发令牌的细节,规定得非常详细。具体来说,一共分成四种授权类型(authorization grant),即四种颁发令牌的方式,适用于不同的互联网场景。
授权码模式(authorization code)
密码模式(resource owner password credentials)
简化(隐式)模式(implicit)
客户端模式(client credentials)
不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌。
2.一般用密码模式和客户端模式比较多。
3.授权码模式:
适用场景:目前市面上主流的第三方验证都是采用这种模式

Spring Security OAuth2和OAuth2.0是一样的吗
OAuth2.0 是一种授权框架,用于授权第三方应用程序代表用户访问受保护的资源。它定义了一组协议和规范,用于实现安全的身份验证和授权流程,以确保用户的隐私和资源的安全性。
Spring Security OAuth2 是 Spring Security 框架对 OAuth2.0 的实现。它提供了在基于 Spring 的应用程序中使用 OAuth2.0 进行身份验证和授权的支持。Spring Security OAuth2 提供了一组可配置的类和过滤器,用于处理 OAuth2.0 的各个方面,例如令牌管理、授权服务器、资源服务器等。

Spring Security OAuth2
Spring Security是一个为基于Spring的应用系统提供安全访问的安全框架。
Spring Security 主要实现了Authentication(认证,解决who are you? ) 和 Access Control(访问控制,也就是what are you allowed to do?,也称为Authorization)

Spring Security在架构上将认证与授权分离,并提供了扩展点。

整合oauth2时除了要引入依赖包还要配置AuthorizationServerConfig授权服务器配置类。
springsecurity的一些配置类WebSecurityConfig也要配置。

授权服务器
略。
整体架构
略。
授权码模式
略。
简化模式
略。
密码模式
略。
客户端模式

更新令牌
略。
基于redis存储Token
略。

我们项目使用的是jwt方式生成token。
jwt缺陷太严重了,泄露之后生效时间内仍然可用?
使用jwt生成token泄露后,生效时间无法控制,只能等到过期时间。

Spring Secuirty Oauth2实现单点登录
A.基于Oauth2跨域单点登录
(基于cookie的,移动端无法使用)
Spring Secuirty Oauth2单点登录实战
Oauth2单点登录除了需要授权中心完成统一登录/授权逻辑之外,各个系统本身(sso客户端)
也需要实现以下逻辑:

  1. 拦截请求判断登录状态
  2. 与 UAA授权中心 通过 Oauth2授权码模式 交互完成登录/单点登录
  3. 保存用户登录信息
    以上逻辑只需使用一个 @EnableOAuth2Sso 注解即可实现
    也就是说上面3步操作都无需我们自己实现,只要声明@EnableOAuth2Sso注解,oauth2会
    帮我去实现。
    基于Oauth2跨域单点登录是基于cookie的,所以如何是移动端要用的话,这种方式就不适用。可以用基于微服务方案(整合网关来实现),下面会讲。
    B.Oauth2整合网关实现微服务单点登录
    网关整合 OAuth2.0 有两种思路,一种是授权服务器生成令牌, 所有请求统一在网关层验证,判断权限等操作(即在网关进行认证授权);另一种是由各资源服务处理,网关只做请求转发。 比较常用的是第一种,把API网关作为OAuth2.0
    的资源服务器角色,实现接入客户端权限拦截、令牌解析并转发当前登录用户信息给微服务,这样下游微服务就不需要关心令牌格式解析以及OAuth2.0相关机制了。
    网关在认证授权体系里主要负责两件事:
    (1)作为OAuth2.0的资源服务器角色,实现接入方权限拦截。
    (2)令牌解析并转发当前登录用户信息(明文token)给微服务
    微服务拿到明文token(明文token中包含登录用户的身份和权限信息)后也需要做两件事:
    (1)用户授权拦截(看当前用户是否有权访问该资源)(还是要和其它后端同事确认下,授权控制是在哪做的?)
    (2)将用户信息存储进当前线程上下文(有利于后续业务逻辑随时获取当前用户信息)
    我们智能运维项目整合了网关访问微服务。但是没有整合网关实现微服务单点登录(即没有实现单点登录)。
    在使用token访问资源的时候会走第5步校验token,如果我们使用jwt校验方式(使用jwt api校验方法),此时就是直接在网关进行校验(减少一次调用授权服务器),如果是其它则会调用授权服务器进行校验。
    网关如何整个auth实现单点登录 kdm。

JWT
a.OAuth 2.0是当前业界标准的授权协议,它的核心是若干个针对不同场景的令牌颁发和管理流
程;而JWT是一种轻量级、自包含的令牌,可用于在微服务间安全地传递用户信息。
b.JWT可以使用HMAC算法或使用RSA的公钥/私钥对来签名,防止被篡改。
c.JWT令牌的优点:

  1. jwt基于json,非常方便解析。
  2. 可以在令牌中自定义丰富的内容,易扩展。
  3. 通过非对称加密算法及数字签名技术,JWT防止篡改,安全性高。
  4. 资源服务使用JWT可不依赖授权服务即可完成授权。
    缺点:
    JWT令牌较长,占存储空间比较大。
    d.JWT组成
    一个JWT实际上就是一个字符串,它由三部分组成,头部(header)、载荷
    (payload)与签名(signature)。
    e.Spring Security Oauth2整合JWT
    在springcloudNew项目中,我们直接把JwtTokenStoreConfig中的信息整合到
    AuthorizationServerConfig中了,没有分开。
    通过使用token增强接口来自定义token信息,比如加入user信息。
    在这里插入图片描述在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值