关于Java应用部署发布生产方案探讨

本文就项目上线部署发布做一些探讨,只做抛砖引玉,错漏之处欢迎评论指出,+V luosanlechang

背景

我们日常的生产发布很多团队都是停服发布新版,其实在用户量访问频繁,规模大的系统,很多是不允许停服升级的,或者他们选择半夜发布,其实都是很不明智的做法,不仅花时间而且花精力。

试想一下,一个正在运行 Java 应用如果突然将其停止,影响不止数据丢失,还会造成其他影响。比如:

  • 请求丢失:内存队列中等待执行请求丢失
  • 数据丢失:处于内存缓存中数据未持久化到磁盘
  • 文件损坏:正在写的文件没有没有更新完成,导致文件损坏
  • 业务中断:处理一半的业务被强行中断,如支付成功了,却没有更新到数据库中
  • 服务未下线:上游服务依然往停止节点发送请求

所以在关闭服务之前,我们需要先做好善后工作,比如保存数据,清理资源,下线服务,然后才退出应用。这种有计划平滑的关闭应用相对直接停止应用,就显得非常『优雅』。

同理,前端发布页面版本也会出现这种访问和缓存错误问题。

因为选择合理的发布方式尤其重要,不同规模的团队和应用也有不同阶段的发布方式选型。

常见发布方式

  • 停机发布
  • 功能开关发布:利用代码中的功能开关(Feature Flag/Toggle/Switch)来控制发布逻辑。
  • 蓝绿发布:两套环境交替升级,旧版本保留一定时间便于回滚。
  • 金丝雀发布(灰度发布):小比例发布,测试通过后再全量,例如 2% 的服务器,主要做流量验证用,也称为金丝雀 (Canary) 测试(国内常称),以前旷工开矿下矿洞前,先会放一只金丝雀进去探是否有有毒气体,看金丝雀能否活下来,金丝雀发布由此得名。
  • 滚动发布:在金丝雀发布基础上的进一步优化改进,是一种自动化程度较高的发布方式,用户体验比较平滑,是目前成熟型技术组织所采用的主流发布方式
    更多可以进入如下
    https://www.cnblogs.com/apanly/p/8784096.html
    https://www.cnblogs.com/nulige/articles/10929182.html
    在这里插入图片描述

发布愿景

相信很多人都希望不再停机发布,减少开发和运维无谓的等待,在服务器较多情况下使用滚动式发布,按批次更新发布,
每次发布时

  • 先将老版本 V1 流量从 LB(Load Balance) 上摘除
  • 清除老版本V1
  • 发新版本 V2
  • 再将 LB 流量接入新版本V2

这样可以尽量保证用户体验不受影响。
从流程可以看出,主要涉及到了负载均衡切换(动态扩容缩容)和服务的优雅关闭
在这里插入图片描述

优雅关闭、扩容缩容

为了实现上述愿景,流程如下,而对于下面这个流程。其实大团队普遍自动化了或者更加丰富细化,小团队或者传统团队基本就是手动切换流量,手动启停服务。方案也是各有各家轮子。
在这里插入图片描述
目前的几种Web容器都没有现成的优雅升级方案. 意味着重启过程中总会存在部分请求失败的情况。如果结合nginx, 理论上可以做到无感升级:

  • 把准备停机的节点从Nginx上摘除, 这样新的请求就不会再发往待停机节点

  • 在Web容器停机之前,让系统处理完已有请求并成功返回给客户端后再彻底停机。

  • 升级成功后,再把该节点挂载到Nginx上.

优雅关闭

因此首先是需要对于Tomcat容器的优雅关闭进行编码,在清除老版本V1上就涉及到了优雅关闭的问题主要思路是

Tomcat容器的优雅关闭 -> Spring容器的关闭->其他容器或中间件

主要涉及到的技术如

  • Spring Boot Actuator
  • ShutdownHook(钩子)
  • SignalHandler
  • Servlet的destory

方面的一些代码嵌入或者改造。

Spring Boot Actuator 是 Spring Boot 的一大特性,它提供了丰富的功能来帮助我们监控和管理生产环境中运行的 Spring Boot 应用。

感谢生哥分享下面这篇亲身实战经验好贴!!!

扩容缩容

对于nginx的上线下线机器,主要是涉及到了扩容缩容的方案
因为下面方案涉及到了一些微服务的方案,所以先拿一个微服务框架预热下。

Dubbo简答概述

首先要补一下基础知识

Spring Cloud 微服务总体架构图

RPC微服务框架Dubbo的设计模型
在这里插入图片描述
Dubbo 的RPC 调用流程,这里主要涉及到4个模块:

  • Registry:服务注册,我们一般会采取Zookeeper 作为我们的注册中心,其他服务发现框架详情

  • Provider:服务提供者(生产者),提供具体的服务实现

  • Consumer:消费者,从注册中心中订阅服务

  • Monitor:监控中心,RPC调用次数和调用时间监控

从上图中我们可以了解到整个RPC 服务调用的过程主要为:

  • 生产者发布服务到服务注册中心中
  • 消费者在服务注册中心中订阅服务
  • 消费者调用已经注册的服务
扩容缩容

自动化扩容和缩容还有智能化运维也是我的目标。
但在传统的Nginx后端配置中,修改upstream的server配置是需要reload或者restart。对于应用为长链接、流量大系统,这会影响用户体验。
大多数团队主要区别在于,有些手动修改配置文件的upstream,有些整合了其他微服务的中间件自动化更新配置文件、不同的upstream插件模板、有的整合lua脚本。附京东Nginx平台化实践

顺便蜻蜓点水下前端,前端打包发布升级上面的工程化问题也是涉及到了很多设计思想,感谢浴池大佬分享的这篇干货
其中一个比较值得了解的是Rails中的Assets Pipeline 详情见:大公司里怎样开发和部署前端代码

服务的监控和管理

先了解下集群的一些技术知识基础
https://www.cnblogs.com/hadoop-dev/p/5925916.html

下面很多工具已经集监控、调度、负载均衡于一身,提供了极大地便利。

微服务化、Docker容器化后的应用比较多现有方案做部署发布和监控。
然而传统应用,一般就是直接使用Nginx做负载均衡,然后搭建Tomcat集群,集群数多,涉及到配置文件管理和集群每个机器的性能指标监控,于是监控工具和部署配置管理尤为重要。

一、监控工具
Java Web做集群部署,最直接需要注意如:

  • 缓存共享,如session共享、项目中用到的内存缓存等,
  • 定时任务

对于上线发布是否成功,已经之后的运行状态,监控至关重要
分布式应用容器化部署的监控方式五花八门:

普通的Tomcat集群的话监控方式比较原始,比如

二、集群调度系统

十大主流集群调度系统大盘点

  • Google Borg
  • Kubernetes
  • Docker Swarm
  • 腾讯 Torca
  • 阿里飞天伏羲
  • Apache Mesos
  • Apache Hadoop YARN
  • Google Omega

三、集群配置和发布管理

下面是一些业界和自研发的一些方案可作为参考

  • 当当的Config Toolkit
  • Apollo(阿波罗):是携程框架部门研发的配置管理平台,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性。
  • K8S:容器编排工具,Kubernetes是Google 2014年创建管理的,是Google 10多年大规模容器管理技术Borg的开源版本。它是容器集群管理系统,是一个开源的平台,可以实现容器集群的自动化部署、自动扩缩容、维护等功能
  • Rancher、Mesosphere 、Openshift
  • Etcd+Confd实现Nginx配置文件自动管理,这种方式可以参照使用到Java的应用配置文件管理

使用Jenkins停机发布方案

上面是一些应用发布升级方案包含扩容缩容等的探讨,那么接下来大篇幅交给停机发布篇,基于当前项目实际情况,我主要介绍下比较原始但是大多数普通团队能用的应用升级方案。
在这里插入图片描述

下面大量篇幅进入Jenkins构建发布技术详解
Jenkins构建项目简易教程
https://blog.csdn.net/u011456337/article/details/103344140

错漏之处欢迎评论指出!
附上本人的V luosanlechang,内部价格,技术交流欢迎!同时欢迎咨询购买都有最优惠!
在这里插入图片描述
在这里插入图片描述

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