1.代码发布脚本

# vim alisz_rsync_chinasoft.cn.user.sh

#!/bin/bash
# 脚本中最后一个管道命令返回非0 就退出
set -e 
# 脚本中管道命令返回非0 也退出
set -o pipefail
# 脚本中变量存在空 就退出
set -u

###########################################################################################
# jenkins拉取git代码同步到 代码中转机 上 然后触发 代码中转机 上的该脚本进行 目标 机房的同步#

# 1.2020.07.17初始化模板
# 2.修改版本记录
###########################################################################################

## 脚本中最后一个管道命令返回非0 就退出
set -e 

## 脚本中管道命令返回非0 也退出
set -o pipefail

## 脚本中变量存在空 就退出
set -u

## 非apache用户运行脚本,则退出
if [ `whoami` != "apache" ];then
        echo " only apache user can run me"
        exit 1
fi

## 密码以及排除文件
passwd="/data/www/.rsync/rsyncd.chinasoft.cn"
exclude_list="--exclude=.svn --exclude=.git --exclude=.gitignore --exclude=*.log --exclude='logs/' --exclude=.gitattributes --exclude=node_modules"


## cn all
yt_cn_ip_list_all="1.1.1.1 1.1.1.2"
yt_ip_list_cn_web01="1.1.1.1"
yt_ip_list_cn_web02="1.1.1.2"

## src directory 源
src_directory="chinasoft.cn/user"

## dst directory 暂不需要
dst_directory="chinasoft.cn/httpdocs/user"

## 时间变量
Date=$(date +'%Y%m%d%H%M%S')
DATE_Y=$(date +'%Y')
DATE_M=$(date +'%m')
DATE_D=$(date +'%d')

## 日志目录
pubMsgDir=/data/www/logs/rsync_log/$DATE_Y/$DATE_M/$DATE_D
pubMsgFile=${pubMsgDir}/${Date}.log

if [ ! -d ${pubMsgDir} ];then
        mkdir -p ${pubMsgDir}
fi

## code同步状态
function func_rsync_status()
{
        if [[ $? == 0 || $? == 23 ]];then
                rsync_edit=1
        else
                rsync_edit=0
                echo "`date` 同步到目标失败! " | tee -a ${pubMsgFile}
                exit 1
        fi
}

## 同步所有机房,目前只有alisz一个机房
function rsync_yt_cn_all()
{
for ip in ${yt_cn_ip_list_all}
do      
        echo "#################### Run rsync ${ip}  start ################################" | tee -a ${pubMsgFile}
        rsync -zavP --delete $exclude_list --password-file=$passwd /data/www/vhosts/${src_directory}/ apache@${ip}::apache/data/www/vhosts/${dst_directory}/ | tee -a ${pubMsgFile}
    func_rsync_status
    ssh -p 2020 apache@"$ip" "/bin/bash /usr/local/worksh/node_cnchinasoft_user_manager.sh restart"
        echo "################### Run rsync ${ip} end #######################" | tee -a ${pubMsgFile}
done
}


## 同步alisz机房的第1台web机器
function rsync_yt_cn_web1()
{

for ip in ${yt_ip_list_cn_web01}
do
        echo "#################### Run rsync ${ip}  start ################################" | tee -a ${pubMsgFile}
        rsync -zavP --delete $exclude_list --password-file=$passwd /data/www/vhosts/${src_directory}/ apache@${ip}::apache/data/www/vhosts/${dst_directory}/ | tee -a ${pubMsgFile}
    func_rsync_status
    ssh -p 2020 apache@"$ip" "/bin/bash /usr/local/worksh/node_cnchinasoft_user_manager.sh restart"
        echo "################### Run rsync ${ip} end #######################" | tee -a ${pubMsgFile}
done
}

## 同步alisz机房的第2台web机器
function rsync_yt_cn_web2()
{
for ip in ${yt_ip_list_cn_web02}
do
        echo "#################### Run rsync ${ip}  start ################################" | tee -a ${pubMsgFile}
        rsync -zavP --delete $exclude_list --password-file=$passwd /data/www/vhosts/${src_directory}/ apache@${ip}::apache/data/www/vhosts/${dst_directory}/ | tee -a ${pubMsgFile}
    func_rsync_status
    ssh -p 2020 apache@"$ip" "/bin/bash /usr/local/worksh/node_cnchinasoft_user_manager.sh restart"
        echo "################### Run rsync ${ip} end #######################" | tee -a ${pubMsgFile}
done
}


#####################  MAIN  ###############################
usage () {
        echo ""
        echo "  Please Input server infomation!"
        echo ""
        echo "  USAGE: `basename $0` [all|yt_cn_web1|yt_cn_web2]"
        echo ""
}
        
if [ $# != 1 ]
then
        usage >&2
        exit 1
fi
OPT=$1
case $OPT in
all)
        echo "start rsync `basename $0` to all servers"
        rsync_yt_cn_all
        ;;
yt_cn_web1)
        echo "start rsync `basename $0` to yt_cn_web1 servers"
        rsync_yt_cn_web1
        ;;
yt_cn_web2)
        echo "start rsync `basename $0` to yt_cn_web2 servers"
        rsync_yt_cn_web2
        ;;
*)
        echo "Usage:`basename $0` [all|yt_cn_web1|yt_cn_web2]"
        ;;
esac

2.远端重启node程序脚本
# cat /usr/local/worksh/node_cnchinasoft_user_manager.sh

#!/bin/bash
#
source /etc/profile

# 根据参数,执行进程的启动 停止 重启等

# 非apache用户运行脚本,则退出
if [ `whoami` != "apache" ];then
echo " only apache can run me"
exit 1
fi

export NODE_ENV=production


node_process='cnchinasoft_user'

##############node_chinasoft_user###############
#1.启动 node_chinasoft_user
start_node_chinasoft_user() {
    #pid=`ps -ef |grep $node_process |grep -v grep |awk '{print $2}'`
    pid=`pm2 status|grep cnchinasoft_user|grep enabled|wc -l`
    if [[ ${pid} -lt 1 ]];then
        echo "starting node_chinasoft_user process is $node_process;pid is $pid "
        if [ $? -ne 0 ]; then
            echo
            exit 1
        fi
    cd /data/www/vhosts/chinasoft.cn/httpdocs/user && npm install request && npm install && npm install --dependencies
    cd /data/www/vhosts/chinasoft.cn/httpdocs/user && pm2 start npm --watch --name cnchinasoft_user -- run start
        if [ $? == '0' ];then
            echo "start node_chinasoft_user $node_process ok"
        else
            echo "start node_chinasoft_user $node_process failed"
        fi
    else
        echo "node_chinasoft_user $node_process is still running!"
        exit
    fi
}

#2.停止 node_chinasoft_user
stop_node_chinasoft_user() {
    echo -n $"Stopping node_chinasoft_user $node_process: "
    #pid=`ps -ef |grep $node_process |grep -v grep |awk '{print $2}'`
    #if [ ! "$pid" ];then
    pid=`pm2 status|grep cnchinasoft_user|grep enabled|wc -l`
    if [[ ${pid} -lt 1 ]];then
    echo "node_chinasoft_user $node_process is not running"
    else
    cd /data/www/vhosts/chinasoft.cn/httpdocs/user && pm2 stop cnchinasoft_user
    echo "stop node_chinasoft_user $node_process ok killed $pid"
    fi
}

#3.重启 restart_node_chinasoft_user
restart_node_chinasoft_user() {
    stop_node_chinasoft_user
    start_node_chinasoft_user
}

#4.查看 node_chinasoft_user 状态
status_node_chinasoft_user(){
    #pid=`ps -ef |grep $node_process |grep -v grep |awk '{print $2}'`
    #if [ ! "$pid" ];then
    pid=`pm2 status|grep cnchinasoft_user|grep enabled|wc -l`
    if [[ ${pid} -lt 1 ]];then
        echo "node_chinasoft_user $node_process is not running"
    else
        echo "node_chinasoft_user $node_process is running"
    fi
}

#####################  MAIN  ###############################
usage () {
        echo ""
        echo "  Please Input server infomation!"
        echo ""
        echo "  USAGE: `basename $0` [start|stop|restart|status]" 
        echo ""
}
    

if [ $# != 1 ]
then
        usage >&2
        exit 1
fi
OPT=$1
case $OPT in
 
start)
        echo "start `basename $0`"
        start_node_chinasoft_user
    ;;
stop)
        stop_node_chinasoft_user
    ;;
restart)
        restart_node_chinasoft_user
    ;;
status)
        status_node_chinasoft_user
    ;;
*)
    echo "Usage:`basename $0`  [start|stop|restart|status]"
    exit 1
esac

3.node相关的域名配置

[root@alisz-chinasoft-web01:~]# cat /usr/local/nginx/conf/vhost.d/chinasoft.cn.conf

server {
        listen 80;
        server_name     chinasoft.cn www.chinasoft.cn ori-www.chinasoft.cn;
    access_log on;
        access_log      /data/www/logs/nginx_log/access/www.chinasoft.cn_access.log main ;
        error_log       /data/www/logs/nginx_log/error/www.chinasoft.cn_error.log ;
        root            /data/www/vhosts/chinasoft.cn/httpdocs;
        index           index.html index.shtml index.php ;
    include        rewrite.d/chinasoft.cn.conf ;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;

    if ($http_user_agent ~ Ezooms) {
        return 403;
    }

    location ~ ^.*\.(htaccess|htpasswd|ini|sh)$ {
        deny all;
    }

    rewrite ^/(.*)$ https://www.chinasoft.cn/$1 permanent;

}

server {
        listen 443 ssl;

        ssl_certificate         cert2016/chinasoft_cn.crt;
        ssl_certificate_key     cert2016/chinasoft_cn.key;
        ssl_dhparam     cert2016/dh_2048.pem;

        ssl_session_timeout     5m;
        ssl_protocols   TLSv1.1 TLSv1.2;


        ssl_ciphers     "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!AES128-GCM-SHA256:!AES256-GCM-SHA384:!AES128-SHA256:!AES256-SHA256:!AES128-SHA:!AES256-SHA:AES:!CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";


        ssl_prefer_server_ciphers       on;

        server_name     chinasoft.cn www.chinasoft.cn ori-www.chinasoft.cn;
    access_log on;
        access_log      /data/www/logs/nginx_log/access/www.chinasoft.cn_access.log main ;
        error_log       /data/www/logs/nginx_log/error/www.chinasoft.cn_error.log ;

        root            /data/www/vhosts/chinasoft.cn/httpdocs;
        index           index.html index.shtml index.php ;
        include         rewrite.d/chinasoft.cn.conf ;
        error_page  404 403              /404.html;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;

        if ($http_user_agent ~ Ezooms) {
        return 403;
    }

    location ~ ^.*\.(htaccess|htpasswd|ini|sh)$ {
        deny all;
    }

    location ^~ /support/ {
            proxy_pass http://support_servers/;
        }


    location /templates/ {
            proxy_pass http://node_servers;
        }

    location ^~ /online/ {
        try_files $uri $uri/ /online/home.html;
        index home.html index.html;
    }


    location ^~ /user/ {
        proxy_pass http://user_servers;
    }

    location ~* ^/server/(.+)$ {
        alias /data/www/vhosts/chinasoft.cn/httpdocs/maxserver/;
        index index.php index.html;
        try_files $1 $1/ /server/public/index.php?$query_string;
        location ~* ^/server/(.+)\.php$ {
            add_header Cache-Control no-store;
            fastcgi_pass   unix:/tmp/php-cgi.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$1.php;
            include        fastcgi_params;
        }
    }


    location ~ \.php$ {
        fastcgi_pass   unix:/tmp/php-cgi.sock;
        #fastcgi_pass   unix:/tmp/php-cgi.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

        #location / {
        #        try_files $uri $uri/ /home.html;
        #        index home.html home.html;
        #}

}

4.后端upstream

upstream node_servers{
    ip_hash;
    server 172.18.10.1:2233 max_fails=2 fail_timeout=30s weight=1;
    #server 172.18.10.2:2233 max_fails=2 fail_timeout=30s weight=1;

    check interval=3000 rise=2 fall=5 timeout=1000 type=tcp port=2233;
    check_keepalive_requests 100;
}

upstream user_servers{
    ip_hash;
    server 172.18.10.1:1111 max_fails=2 fail_timeout=30s weight=1;
    #server 172.18.10.2:1111 max_fails=2 fail_timeout=30s weight=1;

    check interval=3000 rise=2 fall=5 timeout=1000 type=tcp port=1111;
    check_keepalive_requests 100;
}

upstream support_servers{
    ip_hash;
    server 172.18.10.1:2333 max_fails=2 fail_timeout=30s weight=1;
    #server 172.18.10.2:2333 max_fails=2 fail_timeout=30s weight=1;

    check interval=3000 rise=2 fall=5 timeout=1000 type=tcp port=2333;
    check_keepalive_requests 100;
}

 

通过pm2管理nodejs程序的启动和停止

1.启动模块的方法
user:

cd /data/www/vhosts/chinasoft.cn/httpdocs/user && npm install request && npm install && npm install --dependencies
cd /data/www/vhosts/chinasoft.cn/httpdocs/user && pm2 start npm --watch --name cnchinasoft_user -- run start


# node 问题调试

[apache@alisz-chinasoft-web01:~/vhosts/chinasoft.cn/httpdocs/user]$ node /data/www/vhosts/chinasoft.cn/httpdocs/user/node_modules/.bin/nuxt start

 ERROR  Cannot find module 'axios' from '/data/www/vhosts/chinasoft.cn/httpdocs/user'                                                                                                                                                               16:42:47

  at Function.resolveSync [as sync] (node_modules/resolve/lib/sync.js:90:15)
  at node_modules/vue-server-renderer/build.prod.js:1:77685
  at Object.<anonymous> (webpack:/external "axios":1:0)
  at __webpack_require__ (webpack/bootstrap:25:0)
  at Object.<anonymous> (api/edApi.js:1:0)
  at __webpack_require__ (webpack/bootstrap:25:0)
  at Module.<anonymous> (store/index.js:1:0)
  at __webpack_require__ (webpack/bootstrap:25:0)
  at updateModules (.nuxt/store.js:9:0)
  at Module.<anonymous> (.nuxt/store.js:17:0)



# 经过分析发现是远程跳板机安装过axios,并且产生了粘性,直接切换到apache用户是不行的,切换到 yt_devadmin 再次切换到 root 才能安装 axios,并且要在模块的当前目录下

[root@alisz-chinasoft-web01:/data/www/vhosts/chinasoft.cn/httpdocs/user]# su yt_devadmin
[yt_devadmin@alisz-chinasoft-web01:/data/www/vhosts/chinasoft.cn/httpdocs/user]$ sudo su root
[root@alisz-chinasoft-web01:/data/www/vhosts/chinasoft.cn/httpdocs/user]# npm install axios
npm WARN deprecated axios@0.19.2: Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410

> nodemon@1.19.4 postinstall /data/www/vhosts/chinasoft.cn/httpdocs/user/node_modules/nodemon
> node bin/postinstall || exit 0

Love nodemon? You can now support the project via the open collective:
 > https://opencollective.com/nodemon/donate

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules/nodemon/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules/watchpack-chokidar2/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

+ axios@0.19.2
added 107 packages from 108 contributors and audited 1549 packages in 11.334s

59 packages are looking for funding
  run `npm fund` for details

found 6 vulnerabilities (4 low, 2 high)
  run `npm audit fix` to fix them, or `npm audit` for details


# 如下 node_modules/axios 这个模块必须要在指定用户下进行安装,其他用户安装不上
[root@alisz-chinasoft-web01:/data/www/vhosts/chinasoft.cn/httpdocs/user]# find ./ -name axios
./node_modules/@nuxtjs/axios
./node_modules/@nuxtjs/axios/node_modules/axios
./node_modules/axios