知识点四:四层和七层负载均衡,循环依赖,轮询和心跳,项目安全,dubbo,灰度发布,Get和Post

四层负载均衡和七层负载均衡

  1. 四层负载均衡,是指基于 ip + port 的负载均衡,实现有 LVS,F5;

  2. 七层负载均衡,是基于 url 的负载均衡,通过域名来路由到后面真实的服务器 ip,实现有 Nginx;

spring 循环依赖

  1. 循环依赖,是指 ClassA 有一个成员遍历是 ClassB 的实例,反过来 ClassB 有一个成员变量是 ClassA,如此在构造的过程中,就会造成一个死循环;

  2. 循环依赖分为构造循环依赖和属性循环依赖,属性循环依赖就是通过先执行构造,得到一个早期引用,这样在随后的属性设值时使用早期引用,不必将依赖 bean 的属性注入执行完才能使用,构造循环依赖需要通过 @Lazy 推迟初始化的过程来解决;

  3. spring 加载 bean,是先调用构造实例化,然后进行属性注入,最后放入缓存中,并且 spring 对 bean 的缓存分为三级,一级存放完全初始化完成的 bean,二级存放早期bean 的引用,尚未完成属性注入,三级存放实例化完成的bean 工厂;

	首先 对象 ClassA 完成实例化,并放入三级缓存中,接着进行属性装配,发现需要 ClassB 的实例
	然后,创建 ClassB 的实例,也是实例化完成后,放入三级缓存中,执行属性装配,发现需要 ClassA 的实例
	第三步,又进入 ClassA 实例化过程,发现三级缓存有,此时升级到二级缓存中,且直接返回给 ClassB 的属性装配过程
	第四步,那么 ClassB 就完成了属性装配,被放入到一级缓存,并返回给第一步
	第五步,回到最开始,ClassA 的属性装配也完成,也被顺利放到一级缓存中

验活的两种方式:轮询和心跳

  1. 轮询是指,服务端定时请求客户端,客户端返回应用当前状态,根据应用的返回,服务端保存和更新客户端的状态;

  2. 心跳是指,客户端定时请求服务端,更新自己的状态,同时服务端自身有一个定时,检测哪些客户端超时没有来更新自己的状态,将这些客户端置为异常;

  3. 两种方式,都要求服务端保存客户端的状态,但轮询对服务器压力比较大,需要定时发送很多请求,且需要知道所有客户端的地址,而心跳这种方式,就比较灵活,等待客户端建立连接,更新即可;

  4. 心跳的实现,服务端建立 serverSocket 等待客户端连接,通过一个 map 记录客户端状态,如果有连接进来,将其发送的数据更新到 map 中,通过 map 中的信息,就可以获取到所有客户端的状态,额外通过一个定时任务,扫描 map,将最新的心跳时间和当前时间对比,如果超过了设置的超时时间,就更新状态为异常,并将异常状态发送给订阅该客户端的其他客户端,标记该客户端异常不可用;

项目安全

  1. 防 sql 注入,防止恶意 sql 语句在应用数据库执行,体现在 mybatis 的 mapper.xml 文件中,禁止拼接sql,使用占位符的方式传参设置;

  2. 防 xss 攻击,防止恶意 js 脚本渲染给用户;

	前端对特殊字符进行转义
	后端接收请求,也需要转义,通过一个 filter 对请求 body 内容进行转义,参考 XSSFilter
  1. 防 csrf 攻击,防止在用户不知情的情况下向站点发送了敏感请求,用户登陆网站 A,未退出,再登陆网站 B,网站 B 利用 A 的 cookie 未失效,在用户不知情的情况下,向 网站A 发起了请求,特别是敏感操作;
	通过验证码进行特别敏感操作进行校验
	通过设置 cookie 为 httpOnly,防止 js 获取到 cookie
	通过 token 来认证请求	
  1. token 的使用,由服务端产生,登陆后服务端返回给前端一个 token,之后每次请求都会携带 token,避开了 cookie 的同源策略,并且在多个服务端共享,无状态;
	token 需要设置有效期,token 的刷新是通过每次请求验证 token 时,如果发现过期,要求前端重新登陆,服务器生成新的 token,之后请求使用新的 token;
	token 的无状态,可以将状态信息都保存在 token 中,进行散列算法签名即可,每次服务端进行同样的签名来验证是否是自己签发,常用算法 HMAC;
	用户注销,token 应该失效,此时可以在前端控制,当用户注销,要删除该 token;
	更深入的就是 JWT,单点登陆,Oauth认证;

Dubbo

  1. 服务注册,解决 url 管理混乱和变化,服务监控,解决服务调用关系的错综复杂,难分析;

  2. 服务监控中心,需要服务提供者和消费者在本地内存中,保存服务调用次数和调用时间,定时发送到监控中心,由监控中心进行统计分析展示;

  3. dubbo 服务间调用,支持集群容错,默认是 failover,即调用失败后重试其他服务提供者节点,还有 failfast 只发起一次调用,失败后报错,或者 failsafe 失败后直接忽略错误,或者并行调用多台服务器节点,广播调用所有节点;

  4. 服务间的注册和订阅,可以设置为只注册和只订阅的模式,

	只订阅不注册是指服务提供者只订阅注册中心其他服务,而不把自己向注册中心注册,这适用于服务开发者还未上线,测试阶段,避免其他服务消费者调用;
	只注册不订阅是指...
	参考:https://blog.ouyangsihai.cn/dubbo-yi-pian-wen-zhang-jiu-gou-liao-dubbo-yu-dao-chu-lian.html

灰度发布

  1. 灰度发布,是发布新版本应用后,先不切流量,测试通过后,逐步切流量进来,并且部署更多新版本应用,根本是流量控制;

  2. 具体过程是,先启动一个新版本的应用,不切流量进来,测试人员先线上测试,测试通过后,切少量用户流量到新版本,观察运行状态,收集运行数据,与旧版本数据对比,确认新版本运行良好后,逐步导入更多流量,并逐步部署更多的新版本应用,直到流量全部切换,最后关闭旧版本应用,完成发布;

  3. 如果在灰度发布过程中,发现了新版本有问题,需要立即将流量切回旧版本,将负面影响控制在最小范围;

  4. 灰度发布的实现,将新版本应用标记为灰度节点,当服务消费者调用服务提供者时,通过 java agent 技术改变服务路由策略,不路由到灰度节点,或者细粒度到哪些消费者路由到灰度节点,如此控制流量的走向;

	java agent 技术,可以在运行期将已经加载的类的字节码做变更,实现不重新部署应用,但改变应用的代码逻辑
  1. 控制服务路由,如 springcloud 应用,控制负载均衡组件 Ribbon 的返回,如 dubbo 应用,控制 LoadBalance 的返回,根据请求头中的特殊字段,或者按照比例分发请求,路由到正常节点或者灰度节点,起到流量控制;

Get 和 Post

  1. 两者底层都是 tcp 连接,上层 http 协议也只规定了请求行,请求头,请求体,响应行,响应头,响应体的数据交互规范,区分了get,post 等请求方法的不同语义,但没有限制 get 和 post 在数据交互上有任何局限性,理论上, get 请求,也可以在请求体传输数据,post 请求,也可以将参数拼接到 url 之后;

  2. get 方法的语义是用于获取后台信息,请求参数通常是拼接在 url 后面,由于直接可见,不太安全,且 url 的长度会受到浏览器和服务器的限制,而 post 方法的语义是修改后台信息,请求参数通常是放在请求体中,抓包后也是可见的,请求体大小不受限制;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章