0
点赞
收藏
分享

微信扫一扫

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


为什么我们作为一个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 joinpay@10.10.10.129 -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/



----------------------------



 



 

举报

相关推荐

0 条评论