⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 cnblogs.com/yougewe/p/10327217.html 「等你归去来」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

谈到线上环境,一般开发同学,不太容易接触到。即使接触到,也只是其中的冰山一角!

所以,其实说起线上环境的部署,咱们好像都有点懂,但是又都不一定完全懂!网上的知识无穷无尽,但往往都是各司一职,对于普通同学,很难窥其全貌!

所以,我今天就来说说,一些普通的线上环境的部署步骤,和一些脚本小技巧吧。只希望通过这篇文章,能够让大家有一个运维的全局观!

我将会分几条线来整理咱们的运维思路!

一、从理论上讲,我们应该怎么做?

1.针对的是什么样的用户群体,体量大概会有多少?

这是一个部署规划的前题。为啥呢?

一、如果你针对的是后台管理员,人数也不多,那么你可能只需要一个服务器就可以了,前后端也都可以部署在同一台服务器上;如果稍微考虑下单点故障问题,则顶多两台服务器搞定!

二、如果针对的是前端普通用户,那么,往往就会考虑多机部署,前后端分离,单点问题,负载均衡了;至于具体要部署多少台,则要根据你的用户情况来定了,当然,前期一般没必要部署很多台服务器!更多的考虑是横向扩展的能力。只要能支持横向扩展,则短期内,往往不用担心性能和架构问题!

2.为支持预估的用户量,大概需要多少的带宽?    有访问就会有流量产生,而预估的用户量,则是一个带宽资源需求的一个决断依据!

一般针对前期用户不太确定的场景,可以先买个 10M 左右的共享带宽,基本能够应付;经过一段时间的观察后,再进行带宽的变更也可以;

当然,考虑带宽,自然也会存在一个公网IP的问题,因为流量是从IP进来的。而在IP之前,则是域名的访问。域名问题则又涉及到DNS,不必细说!

公网IP可以是直接指向机器的,也可以是指向负载均衡器的。如果想要支持横向扩展,则IP的指向一定是一个负载均衡器。因为只有这样,当遇到流量突增,或者做活动的时候,才能更快速的进行扩容!

3.数据库规划如何?

数据在当下时代,算是重中之重了。机器没了可以再买,代码没了可以再写,但是数据没了就完蛋了!

数据库一般要遵从几个基本原则: 一、带宽要大; 二、运算速度要快; 三、要能承受足够大的运算空间;(即:带宽足够大/cpu核数够多/内存容量够大/最大并发连接数/…)

所以,一般不要在数据库上省钱,能多点就多点!

另外,也不要什么样的数据都往数据库(关系型数据库)存,搞清楚各类型数据库的强项与弱项,做出明智的选择。否则会带来很多不必要的麻烦!

4.应用要基于操作系统来部署还是基于容器来部署?

这是个决策性的问题!基于操作系统的部署,是一种比较传统和常见的部署方式。优点是,很多系统工具都是完善的,只要你大概知道要部署什么,部署下来一般不会有太多问题,因为这是个完整的系统。

但是,由于系统与系统之间可能不能完全一致,有各种各样的差异,所以,你在这个机器上运行成功的东西,在另外的机器上则不一定能成功。因此,基于系统的部署将会使我们的问题排查难度大大增加,而且移值性会很差。比如你在机器A上安装了10个软件,你可能配置了n个选项,但是,当你在安装B机器的时候,你并不能很好的利用原有的配置,你还得从头一个个地来!

因此,有另一个部署方案,基于容器的部署(我这里是基于docker容器的部署)。docker就类似于一个个的虚拟机,但是它更加轻量级,当一个docker部署好后,你可以任意复制到其他机器上运行,看起来很诱人吧。

不过,docker只是入门级容器,对于大量集群容器的管理,还是显得力不从心,当然你很容易找到另一个方案: Kubernetes (K8s); 你只要花上少许的时间了解下,你就可以应用了!

当然了,使用容器的方案,有没有什么缺点呢?应该是有的,比如本来可以基于系统的监控方案,因为接入容器后,监控指标则不一定适用了,当然现成的方案还是有的,不过得另外再花点时间研究了。再比如:如果容器出了问题,是否能排查出来,这也是另一个问题!

5.都有些什么样的基础设施或者中间件?

想要运行应用程序,自然是先考虑运行环境的。比如:应用需要 nginx 来做http服务器,用 tomcat 来做java web应用服务器,用redis来做缓存中间件,用zk来做应用协调中间件,用rabbitmq来做消息中间件,等等!

因此,要在代码跑起来之前,先要把这些环境给准备好咯。

准备这些中间件或基础设施之前,也要问下当下的形势,是否有高性能高可用应用需求?比如:是否需要集群部署,或者单机部署?往往集群部署又会依赖其他的中间件!也更复杂!

当然,这些都不是事。事儿是在出问题之后,能够有意识,能够猜测到问题发生的点!

6.应用代码应该怎样部署?

当基础环境就绪后,就应该让主角上场了。应用代码怎么部署?

最简单的: 通过ftp上传代码到服务器上后,一个个部署!这种方案是最原始的,也是在没有办法搞更好的方案的时候使用的,不应长期使用;

稍微好点的: 使用集成工具(如jenkins)进行打包,然后上传一个私有yum镜像服务器(yum 源)。然后在线进行yum 安装;这种方式,借助了集成工具,几个好处:

  • 可以检测代码合法性如:单元测试、代码规范(可能需要插件);
  • 对任何的改动有简单留档,可以备查的同时,也为代码的回滚提供了可能;
  • 减少了手动上传导致的包破坏的可能性;
  • 适合大规模应用;

再成熟点的: 再往后面,手动 yum 安装也已经太累了,所以急需一个部署平台,实现自动化部署;(这里的自动化部署可能就是基于CI集成部署的一种升级版)。总之,大大减小了人工参与程序,提升了效率,同时也保证了质量!当然,这种部署平台已经经过了严格的测试,出错的可能性也比较小了!

7.服务器的安全性?

不考虑服务器的安全性的应用,无异于自暴自弃。黑客无处不在,不过幸好现在系统也是越来越完善,只要稍加控制,即不那么容易被攻破了。但是如果放弃安全防护,则随便来一个菜鸟程序员就把你搞死了,那时的损失就大了。

网络安全是个很专业的领域,我不敢造次去谈它。不过我们可以简单的做下防护: 如防火墙、授权操作、病毒库等等。当然,如果使用xx云服务,则轻松方便多了,在后台点点设置几下搞定!

8.服务的可监控性?

无监控,不上线!

这是一个警示,如果线上服务没有监控,则所有线上的东西,都成了盲区,这对程序员GG们来说,简直太糟糕了,虽然他们很自信!

监控分两个方面: 一是系统级别的监控;二是应用级别的监控;(一般忽略其他监控: 如网络)

系统级别的监控一般可以安装第三方的软件来解决: 如 zabbix, grafana …

而应用级别的监控,则需要自己拥有一套监控代码了,而这对初期项目,则往往比较吃力。当然,如果引入一些开源的解决方案也是可以的,比如 ELK, 做到分布式日志中心的作用的同时,也可以根据日志做相应的应用报错监控!然而这又涉及另外的机器费用和人力成本问题,也显得不那么简单了。

而如果使用xx云服务,则往往都会自带服务器监控的,可以很方便地查看到服务器情况,站在高层次预估应用是否存在潜藏的问题!

如上,就是一些个人觉得的在部署一整套线上环境的时候,需要考虑的事项!从理论上讲解了下个人见解,不对之处,请赐教!

二、接下来,我将给到一些实际的操作捷径或提示?(linux)

1.免密登录服务器?

在n服务器之间跳转,如果每次都要求输入密码,那确实太烦了。尤其在密码一般还很不容易记住的情况下!

所以,可以将一台服务器作为跳板机,在这台服务器上,可以免密地登录到允许的n台子服务器;

操作步骤有二:

# 1. 先使用 ssh-keygen 生成本机的key
ssh-keygen -t rsa # 如果已生成不要重复生成
# 2. 使用 ssh-copy-id 将本机的 key 发送到需要免密登录的服务器,首次copy时会要求输入密码,后续则免密了
ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.1.2.111

2.服务器之间文件(夹)拷贝?

拷贝文件的目的有很多,比如:代码同步,文件同步,资源同步,甚至是会话同步….

# 1. 使用scp 拷贝文件
scp /home/ol-web.war root@xxx.com:/www/tomcat/wepapps/ # 从本机拷贝到远程
scp /home/ol-web.war root@xxx.com:/www/tomcat/wepapps/ # 从远程拷贝到本机
scp -r /www/nginx/html/ root@$1.2.3.2:/www/nginx/html/ # 从本机拷贝文件夹到远程
# 2. 使用 rsync 同步文件,(可能需要安装 rsync 服务)
rsync -av --delete /www/nginx/html/ root@$1.2.3.1:/www/nginx/html/ # 同步所有属性,本地删除的文件也同步远程删除

其中,scp一般是系统自带的命令,而rsync则需要自行安装服务。

scp复制你可以认为是增量复制,所以远程文件往往会越来越大,垃圾文件越来越多。

而rsync则是保持两端完全一致,可能会符合应用场景!但是,别忘了把rsync服务加入到开机启动项中!

3.快捷使用 ssh 等等命令,使用 tab 键进行信息补全?

当使用 ssh / scp 等等命令操作的时候,其操作对象往往 1.2.3.x 这样的ip显示,如果不能友好点,那确实太累了!我们可以如下操作,以实现 ssh 也能更好的记忆:

# 在文件 /root/.bashrc 中,添加脚本如下,使自动补全添加 ssh
# auto complete ...
complete -W "$(echo $(grep -v '^$|#' .ssh/config | sort -u | sed 's/^ssh //'))" ssh
# 在文件 /root/.ssh/config 中,添加需要自动补全的服务器,
Host 172.2.3.5 server-api-01
Host 172.2.3.6 server-api-02
# 以上服务器名字需要在 /etc/hosts 文件中添加相应解析
# 而登录 server时,只需, ssh server-api-01 即可

如上补全工作,无需在所有服务器上进行操作,只需在相应的跳板机上提供功能即可!

4.简要 saltstack 搭建指南?

salt 是个方便易用的集群管理工具,比如你可以用于批量重启服务,全局搜索日志等等;

# 1. 安装, 仅需到相应机器上安装即可
yum install salt-master salt-minion
# 2. 配置 /etc/salt/master /etc/salt/minion, 最简单的,只需修改 minion 配置,指向 master 的ip即可;
#指定master,冒号后有一个空格, minion
master: 172.1.2.22
id: server-api-01
user: root
# 3. 启动所有节点, status, restart
systemctl start salt-master # 162机器可用
systemctl start salt-minion
/etc/init.d/salt-master start # 155机器可用
/etc/init.d/salt-minion start
# 4. 将所有salt-minion 添加到 master 集群管理
salt-key -A
# 5. 登录跳板机 api_01, 运行salt 操作,执行集群管理工作
salt server-api-02 cmd.run 'lsof -i:80'
salt '*' test.ping

5.简要集群复制shell脚本?

有时,你可能需要将你的应用发布到n台服务中,你可以直接改如下shell,也可以依赖于salt这样的高级工具进行发布!shell 参考如下:

#!/bin/bash
# find out my ip to exclude...
MY_MERCHINE_IP=`ifconfig eth0 |awk -F "[: ]+" '/inet addr/{print $4}'`;
MERCHINE_IP_LIST="172.1.2.7 172.1.3.4";
for m_ip in $MERCHINE_IP_LIST;
do
if [[ $m_ip != $MY_MERCHINE_IP ]]; then
echo "- Installing apps to mechine@${m_ip} ...";
# install api apps
scp /www/test/hello-1.0.0-SNAPSHOT.jar root@${m_ip}:/www/test/
rsync -av --delete /www/html/ root@${m_ip}:/www/html/
echo "- Install apps to merchine@${m_ip} done.";
fi;
done;

6.简要docker搭建指南?

docker 作为一个容器化的基石,一出世就被追棒。包括现在的 k8s ,也是基于docker的。docker 可以让你在一处搭建,处处运行,从而避免每次新买机器就要搞很久的尴尬局面;其搭建也是很简单的(简单应用):

为方便任意发挥,我们可以基于centos这种系统级别的镜像进行创建自己的image;

# docker 安装:
yum install docker
service docker start
# 拉取 centos6 的 docker 镜像
docker pull centos:6
docker images
# 构建一个 image, 创建空目录,编辑 Dockerfile
vim Dockerfile # 内容可变
FROM centos:6
MAINTAINER oom <w@163.com>
# move all configuration files into container

# RUN yum install -y lsof
# EXPOSE 80
# CMD ["sh","-c","service httpd start;bash"]
# 创建镜像
docker build -t tmp_image:1.0 .
# 创建并运行容器
docker run -h tmp_container -itd --name tmp_container -v /opt/docker/webapps:/www/webapp tmp_image:1.0
# 进入容器,相当于进入 centos 操作系统
docker exec -it tmp_container bash
# 保存容器修改到images
  docker commit -m 'web final.' 49d79fc19eaa tmp_image:1.2
# 备份容器修改后的docker镜像
  docker save > /opt/images/images_final/tmp_image.final.tar tmp_image:1.2
# 恢复你的备份镜像,即全网发布
# 可以在任何装 docker 的地方加载保存的镜像
  docker load -i /opt/images/images_final/tmp_image.final.tar

7.定制你的登录欢迎语?

由于可能存在线上环境与测试环境共存的情况,一不小心的切换错误,就可能导致不可挽回的损失。所以,如果我们能在登录的时候,做一个简单的提示,那么就会少一点出错的可能性。所以,订制你的登录欢迎语吧!

# 修改登录欢迎语 vim /etc/motd
*****************************************************************
!!! WARNING: 欢迎来到线上机器: service-api-01 ,请谨慎操作哦 !!!
*****************************************************************

这样,用户登录后,就会清楚的知道自己是在操作生产环境了!

8.更方便的查看nginx的访问日志?

对于后端的日志而言,往往都是主动打印到某个固定位置,从而开发人员可以直接使用 tail -f xxx.log 进行日志的查看!

然而对于前端的代码而言,则往往没有相应的开发日志,唯一可以借助的就是 http 服务器的日志来排查问题了!

所以,比如使用 nginx 作为 http 服务器,那么就应该把尽可能多的有用日志打印出来。那么,如何快速查看 nginx 日志,则是有必要的!比如我们可以这样:

# vim /usr/bin/log_nginx_host , 使用 log_nginx_host 直接查看所有 nginx 日志
tail -f /var/log/nginx/access.log /var/log/nginx/error.log

如上,将会把访问日志与错误日志一起打印出来,从而快速定位问题!

文章目录
  1. 1. 一、从理论上讲,我们应该怎么做?
  2. 2. 二、接下来,我将给到一些实际的操作捷径或提示?(linux)
  3. 3.