关于linux中各种服务注意点及其脚本编写的技巧

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28666081/article/details/85375789
为什么我们作为一个Java开发需要懂linux?
我觉得是因为开发的各种服务毕竟是需要自己搭建的,运维只是协助我们监控环境、处理服务器硬件、管理部署上线的过程等。所以如果我们想变成高级开发工程师或更高的架构师,就必须需要学会处理linux一些基本的问题,做到半个运维的程度。
 
服务搭建过程中常见的问题一般是什么原因引起?
!!权限、权限、权限!!重要的事说三次
在环境能正常搭建的情况,如果权限滥用可能会导致一些奇怪的问题,以下会举例子做说明。
众所周知,linux的权限以权限组区分,而每个文件/文件夹对于权限会分为三部分_rwx rxw rwx 对应 “可读可写可执行(拥有权的用户) 可读可写可执行(同组用户) 可读可写可执行(其他组用户)"。
 
正式因为上面这样,所以对于用户不同组的权限是不一样的,需要谨慎分配,举例一个因为root用户乱用导致问题(也很常见):
 程序员A登录用户 normal 在他的home目录启动了对应的web应用,当前web应用会在对应的log目录生成日志(当前log文件拥有权是normal)。某一天服务器出问题了,需要重启。程序员A不在,这时候程序员B跑去重启,但是程序员B是个新手,他又刚好有root用户,他就直接用root去重启了,然后此时web引用进程就是root用户进程,这样导致后续一些自动构建工具如jenkins(请看我jenkins的文章)就无法对其重新部署(因为没有权限啊),而且就算用root杀掉当前进程然后再用normal重启,之前的生成的log日志也是root,也会导致日志写入异常的问题。
从上面可知,linux的权限是很重要的,不能随意给别人分配权限,自己也不能乱用,能用部署用户就尽量避免使用root(计算自己有)。
 

说完上面的权限用户乱用问题,大家应该有个印象(如果想了解更多可自行学习)。接下来说一下我们开发一些服务脚本是怎么编写的。
 
1 针对一个Java项目编写脚本(批量启动java项目):
# 环境变量
JAVA_HOME=/usr/local/jdk1.7.0_72
CLASSPATH=.:$JAVA_HOME/lib
PATH=$PATH:$JAVA_HOME/bin
export JAVA_HOME CLASSPATH PATH
# services目录
services_home=/home/normal/services
# 遍历处理
for application_name in `ls $services_home`
do
    # 应用的进程ID
    application_pid=`ps -ef | grep java | grep ${application_name} | grep -v grep | awk '{print $2}'`
    # 如果应用的进程存在, 杀死该进程
    if [ -n "$application_pid" ]; then
        kill $application_pid
    fi
    # 启动应用服务
    nohup java -jar -Xms256m -Xmx512m -XX:PermSize=32m -XX:MaxPermSize=128m ${services_home}/${application_name}/${application_name}.jar >/dev/null 2>&1 &
done
 
2 redis服务启动例子:
echo "重启开始.........."
echo ".................."
# redis主从部署目录
redis_data_dir=/data/redis
# 遍历处理,先杀掉所有redis相关的进程
for application_dir in `ls $redis_data_dir`
do
    # 应用的进程ID   包含sentinel、redis应用的PID
    redis_pid=`ps -ef | grep redis-server | grep ${application_dir} | grep -v grep | awk '{print $2}'`
    sentinel_pid=`ps -ef | grep redis-sentinel | grep ${application_dir} | grep -v grep | awk '{print $2}'`
    # 判断进程是否存在,存在则杀掉
    if [ -n "$redis_pid" ]; then
        kill -9 $redis_pid
    fi    
    if [ -n "$sentinel_pid" ]; then
        kill -9 $sentinel_pid
    fi   
done    
sleep 1
# 启动,遍历先启动redis实例,在启动sentinel哨兵
for application_dir in `ls $redis_data_dir`
do
   # 启动redis实例
   redis-server /data/redis/${application_dir}/conf/redis.conf
done
sleep 2
for application_dir in `ls $redis_data_dir`
do  
   # 启动sentinel
   redis-sentinel /data/redis/${application_dir}/sentinel-2${application_dir}.conf --sentinel
don
echo "重启结束.........."
 
举例完上面的例子,那就差不多可以学会了吧。接下来我会举一个现实中出新的问题。
出现的原因的是这样的:因为生产环境的问题,导致jenkins拉取svn的前端vue代码时一直卡住了,导致后续的脚本执行流程都没走到,经过我排查之后发现是.svn的问题,所以我把原来脚本发布的流程进行改造,其改造过程如下:
原来的流程如下:
- jenkins构,调用jenkins服务器本地的vue.sh脚本编译当前vuejs项目,然后发布到中转机。
- 分析:上面的流程在其他主机都是没什么问题,但是其中一台拉取出现问题了,所以需要改造。
 
改造后的流程如下:
- 在vue.sh脚本前后各添加一个脚本用于处理这种特殊情况。第一个脚本如下:
-----------------------------------------------------------------
# 目录
workspace=/var/lib/jenkins/workspace
# 1 删除当前.svn
rm -rf ${workspace}/front-web-property/.svn
 
# 2 远程删除旗锐中转机的项目文件
sshpass ssh [email protected] -o StrictHostKeyChecking=no <<DOC
    rm -rf /home/xxxxxx/temp/dist/*
DOC
sleep 1
 
# 3 拷贝vue.sh到/front-web-property目录下用于构建
cp ${workspace}/front-web-property-script/vue.sh ${workspace}/front-web-property/
--------------------
第二个脚本如下:
----------------------
# 当前工作目录
workspace=/var/lib/jenkins/workspace
 
# 1 删除当前front目录的.svn
rm -rf ${workspace}/front-web-property/.svn
 
# 2 将当前文件拷贝到备份然后删除
rm -rf ${workspace}/front-web-property-script/tmpSpace/*
rm -rf ${workspace}/front-web-property-script/tmpSpace/.svn
rm -rf ${workspace}/front-web-property-script/tmpSpace/.*
mv -f ${workspace}/front-web-property/* ${workspace}/front-web-property-script/tmpSpace/
----------------------------
 
 

猜你喜欢

转载自blog.csdn.net/qq_28666081/article/details/85375789
今日推荐