关于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简答概述
首先要补一下基础知识
RPC微服务框架Dubbo的设计模型
Dubbo 的RPC 调用流程,这里主要涉及到4个模块:
-
Registry:服务注册,我们一般会采取Zookeeper 作为我们的注册中心,其他服务发现框架详情
-
Provider:服务提供者(生产者),提供具体的服务实现
-
Consumer:消费者,从注册中心中订阅服务
-
Monitor:监控中心,RPC调用次数和调用时间监控
从上图中我们可以了解到整个RPC 服务调用的过程主要为:
- 生产者发布服务到服务注册中心中
- 消费者在服务注册中心中订阅服务
- 消费者调用已经注册的服务
扩容缩容
自动化扩容和缩容还有智能化运维也是我的目标。
但在传统的Nginx后端配置中,修改upstream的server配置是需要reload或者restart。对于应用为长链接、流量大系统,这会影响用户体验。
大多数团队主要区别在于,有些手动修改配置文件的upstream,有些整合了其他微服务的中间件自动化更新配置文件、不同的upstream插件模板、有的整合lua脚本。附京东Nginx平台化实践
-
降低权重到0 或 移除主机 都能保证服务的安全的退出【但是本人未实践】
-
Consul+Nginx Consul基于Go语言开发, 轻量级, 用于实现分布式系统的服务发现与配置
-
Nacos + Confd 模式 confd 是一个轻量级的配置管理工具,可以通过查询后端存储系统来实现第三方系统的动态配置管理,结合 Nacos 中已注册的 Tomcat 节点信息,并配合 Confd 实时更新 Nginx upstream 来做到 对接入层的 动态扩容与所容。
顺便蜻蜓点水下前端,前端打包发布升级上面的工程化问题也是涉及到了很多设计思想,感谢浴池大佬分享的这篇干货
其中一个比较值得了解的是Rails中的Assets Pipeline 详情见:大公司里怎样开发和部署前端代码
?
服务的监控和管理
先了解下集群的一些技术知识基础
https://www.cnblogs.com/hadoop-dev/p/5925916.html
下面很多工具已经集监控、调度、负载均衡于一身,提供了极大地便利。
微服务化、Docker容器化后的应用比较多现有方案做部署发布和监控。
然而传统应用,一般就是直接使用Nginx做负载均衡,然后搭建Tomcat集群,集群数多,涉及到配置文件管理和集群每个机器的性能指标监控,于是监控工具和部署配置管理尤为重要。
一、监控工具
Java Web做集群部署,最直接需要注意如:
- 缓存共享,如session共享、项目中用到的内存缓存等,
- 定时任务
对于上线发布是否成功,已经之后的运行状态,监控至关重要
分布式应用容器化部署的监控方式五花八门:
普通的Tomcat集群的话监控方式比较原始,比如
- 利用JMX结合Zabbix监控Tomcat集群
- Grafana+Telegraf+Influxdb监控Tomcat集群
- 六款开源java应用性能监控工具
- Stagemonitor 、Terracotta、Tangosol、Haproxy,Terracotta是一款由美国Terracotta公司开发的著名开源Java集群平台,允许用户在不改变现有系统代码的情况下实现单机Java应用向集群化应用的无缝迁移
二、集群调度系统
- 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,内部价格,技术交流欢迎!同时欢迎咨询购买都有最优惠!
标签:缩容,Java,部署,探讨,优雅,发布,集群,监控,服务 来源: https://blog.csdn.net/u011456337/article/details/105707720