精华内容
参与话题
问答
  • 项目部署的完整流程

    千次阅读 2020-07-09 12:26:04
    作为一个合格的程序猿,仅仅会打代码还是远远不够的,项目的部署也是我们必须要会的操作,也就是所谓的上线,将我们本地开发好的项目部署到远程服务器上,使得任何机器都可以通过我们远程服务器的公网ip或者域名加上...

    作为一个合格的程序猿,仅仅会打代码还是远远不够的,项目的部署也是我们必须要会的操作,也就是所谓的上线,将我们本地开发好的项目部署到远程服务器上,使得任何机器都可以通过我们远程服务器的公网ip或者域名加上端口号访问到我们的项目。这篇博客详细的列出每个步骤,并且也列举了在部署过程中常见的问题,看完这篇文章,你一定会有所收获!

    首先,我先给大家捋一下项目部署的流程:

    1. 环境搭建: 我们以当下最流行的springboot项目为例,最终打成的是一个jar包,jar包要在远程服务器上跑起来,环境搭建是第一步,也就是安装jdk环境,至于tomcat的话,springboot自带tomcat,所以不安装也可以;

    2. 数据库的部署: 在本地开发的时候,我们代码里面的数据库连接主机名写的是localhost,之所以这样写了能访问到,那是因为我们的项目和数据库都在我们的本地机器上,所以可以访问到;而如果项目部署到远程服务器上,要访问到数据库,应该先部署数据库,至于数据库连接还能不能写localhost,要分两种情况,如果我们的数据库和项目都部署到了同一台远程服务器上,那可以;如果部署在不同机器上,那显然不行,这种情况的话数据库连接的主机名就需要修改成数据库所部署的那台机器的公网ip或者域名。

    3. 上面两步操作完成之后,就可以把本地打好的jar包上传到远程服务器上,远程服务器进入jar包所在目录,执行 java -jar jar包名 即可启动项目,至此,项目部署完成!

    对于以上的步骤,我再详细的列出:

    【一】数据库部署到远程服务器

    方法一:Xshell连接远程服务器进行命令行操作

    1. 将本地的数据库导出成.sql文件
    2. 在远程服务器中创建一个文件夹,专门存放.sql文件的
    3. 执行rz命令(前提是安装了lrzsz),将本地的.sql文件上传到远程服务器上该文件夹;也可以使用xftp实现文件传输
    4. 登录mysql:mysql -u root -p(回车后输入密码)
    5. 执行.sql文件之前需要先创建对应的数据库
    CREATE DATABASE IF NOT EXISTS 数据库名 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
    
    1. 选中刚刚创建的数据库之后再执行.sql文件:use 数据库名
    2. 执行.sql文件:source ***.sql

    (注意如果我们是在.sql文件所在的文件夹中执行该命令就不用加路径,否则需要加上.sql文件所在路径)

    方法二:本地Navicat连接远程服务器的数据库进行可视化操作

    关于本地Navicat连接远程数据库的操作可参考我另一篇博客: https://blog.csdn.net/can_chen/article/details/107184239

    同样是先将本地的数据库导出成.sql文件,我们可以看下导出来的.sql文件包含了什么内容:
    在这里插入图片描述
    这里只截图了部分,下面开始的都是表结构和表数据,可以看到导出来的.sql文件并没有为我们创建数据库,所以在导入.sql文件之前需要先手动创建数据库,并且在我们导出来的.sql文件中添加一行选中我们的数据库 use 数据库名
    在这里插入图片描述
    以上两步操作没完成的话在导入.sql文件的时候都会报错,显示没有选中数据库,如下图:
    在这里插入图片描述
    操作完成之后,便可以将.sql文件导入远程mysql数据库了。

    【二】项目部署到远程服务器

    1. 当我们已经将数据库部署到远程服务器上,如果数据库和项目部署不在同一台远程服务器上,那么在将项目打成jar包之前需要先修改数据库连接的配置信息,将主机名修改成数据库所部署的那台机器的公网ip或者域名,如果数据库和项目部署在同一台远程服务器上,那么主机名可以继续使用localhost;

    2. Xshell连接阿里云远程服务器,并使用xftp将本地的jar包传输到远程服务器上,如果安装了lrzsz可以直接使用rz命令上传

    3. 放行端口号,部署项目成功之后,要能够访问到项目,还应该在阿里云控制台开放对应的端口(进入阿里云官网)
      在这里插入图片描述
      除此之外,还应该在宝塔面板中的防火墙放行该端口
      在这里插入图片描述
      关于宝塔面板: 其实可以简单的理解成就是用来管理我们服务器的,可视化操作简单,管理方便。我们要在服务器中安装软件,部署环境,除了使用linux命令,也可以使用宝塔面板进行可视化操作,去到宝塔面板里的软件商店即可下载,另外,对于防火墙的端口号放行,通过宝塔面板设置也非常的简单快捷。

      关于服务器的购买教程和宝塔部署的相关操作可以参考视频:https://www.bilibili.com/video/BV177411K7bH

    【三】启动项目

    1. 在Xshell中操作,先进入到阿里云远程服务器中jar包所在的文件夹目录
    2. 使用nohup java -jar jar包名 & 命令运行jar包

    (nohup加上&表示项目可以在后台永久的执行,即使关闭Xshell终端也不会停止运行;如果后面想要停止该项目的运行,可以直接结束该项目端口占用的进程)

    以上命令执行之后会提示:nohup: ignoring input and appending output to ‘nohup.out’,这是正常提示,并不是错误,直接打回车就可以。该提示产生的原因是nohup默认会把标准输出重定向到默认文件nohup.out中,也可以自定义该输出文件,例如:nohup java -jar jar包名 >temp.txt & 但是标准错误输出没有重定向到某个文件,所以会有该提示。
    在这里插入图片描述
    如果想要不输出该提示,省去打回车键的操作,那么可以使用以下命令:nohup java -jar jar包名 2>&1 & 解释:2>&1 是将错误提示信息的输出重定向到标准输出,而这里的标准输出已经重定向到默认文件nohup.out中,也就是说标准的错误提示也直接输出到nohup.out中,所以就没有提示了,也就不用再打回车了。

    【四】需要注意的问题

    1. 如果已经在阿里云控制台开放了项目对应的端口号之后,通过公网ip和端口号还是无法访问项目的话,最大的一个可能就是防火墙的原因,防火墙并没有开放对应的端口号,这时候就可以使用宝塔面板去防火墙设置里放行对应的端口号;
    2. 关于项目运行的端口号,建议在打jar包之前改成不常见的那些端口号,避免出现端口号冲突,例如使用8080、3306、80这些端口号都容易出现端口号冲突,尽量不用。
    3. Linux下解决端口号冲突的方法:
    # 查看所有端口使用情况
    lsof -i
    # 查看具体某个端口使用情况
    lsof -i:端口号
    
    # COMMAND指的是进程名,PID指的是进程号/进程ID
    
    # 通过进程名结束占用端口的进程
    killall 进程名
    # 通过进程ID结束占用端口的进程
    kill 进程ID
    # 通过进程ID强制结束占用端口的进程
    kill -9 进程ID
    

    PS:以上就是整个项目部署的完整流程,如果看了之后还有问题的小伙伴可以私信我,没准能帮得上忙哦!😊

    展开全文
  • 新服务器部署完整流程

    万次阅读 2019-09-03 23:12:41
    配置服务器的登录 一般不要把root用户给其他人使用,而是创建一个普通用户账号,例如我现在创建一个... 为了服务器的安全性,root用户登录配置成秘钥登录 ...对于 CentOS6,可以使用 EPEL 库安装 Docker,命令如下: ...

    配置服务器的登录

    一般不要把root用户给其他人使用,而是创建一个普通用户账号,例如我现在创建一个用户名叫做“laowang”的账号,并且配置它的登录密码。
    在这里插入图片描述

    为了服务器的安全性,root用户登录配置成秘钥登录
    在这里插入图片描述

    安装Docker

    我的是阿里云服务器,操作系统为centos7
    1.添加yum源

    #EPEL (Extra Packages for Enterprise Linux)是基于Fedora的一个项目,为“红帽系”的操作系统提供额外的软件包,适用于RHEL、CentOS和Scientific Linux.使用很简单:1. 首先需要安装一个叫”epel-release”的软件包,这个软件包会自动配置yum的软件仓库。当然你也可以不安装这个包,自己配置软件仓库也是一样的。
    # yum install epel-release –y
    #作用:清除YUM缓存。yum 会把下载的软件包和header存储在cache中,而不自动删除。如果觉得占用磁盘空间,可以使用yum clean指令进行清除,更精确 的用法是yum clean headers清除header,yum clean packages清除下载的rpm包,yum clean all一全部清除。
    # yum clean all
    #yum list是列出所有可安装的软件包列表,包含已安装和未安装的
    # yum list
    

    2.安装并运行Docker

    # yum install docker-io –y
    # systemctl start docker
    

    3.检查安装结果,出现下图结果证明安装成功

    # docker info
    

    在这里插入图片描述

    查看docker版本
    docker version
    docker info
    启动docker
    sudo service docker start
    设置随系统启动
    sudo chkconfig docker on

    安装Docker Compose(当然,这个不是必须的,但是有它会用的更爽)

    查看我另外一篇文章

    创建部署项目需要的容器

    1.新建用于存放项目的目录
    在这里插入图片描述

    2.在新建的项目文件夹内添加以下以下两个文件,这两个文件不是拷贝过去就能用的,需要改一些参数,具体改哪些参数,以及这两个文件的具体内容参考我另外一篇文章https://blog.csdn.net/aimashi620/article/details/89002410
    在这里插入图片描述
    这个时候如果直接执行docker-compose build 和docker-compose up -d 会报如下错误,这是因为网络环境还没配置好
    在这里插入图片描述
    打开docker-compose.yml文件我们可以看到了使用名为master的网络,而我们执行docker network ls可以发现,我们并没有叫做master这个网络环境
    在这里插入图片描述
    这个时候我们就要创建名为master的网络,当然这个名字不是固定的。创建网络的时候可以指定很多参数,具体参数参照官方文档https://docs.docker.com/engine/reference/commandline/network_create/
    在这里插入图片描述

    这个时候再执行docker-compose up -d不会报错了,并且执行docker-compose logs命令也能看到项目启动成功。然后在宿主机通过curl命令进行访问接口,访问成功,到这一步可以说明项目已经部署成功了,但是端口映射,nginx,数据库等等其他服务,下面继续
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    部署Mysql

    1.在服务器上新建一个用于存放mysql服务的目录
    在这里插入图片描述
    2.把一下两个文件拷到该目录下,并在目录中新建一个init.sql文件
    在这里插入图片描述
    Dockerfile

    FROM mysql:5.7
    
    ADD ./init.sql /docker-entrypoint-initdb.d/
    
    RUN chmod a+x $AUTO_RUN_DIR/$INSTALL_DB_SQL
    
    

    docker-compose.yml

    version: '2'
    
    networks:
      default:
        external:
          name: master
    
    services:
       mysql_master:
          image: mysql_master
          container_name: mysql_master
          restart: always
          build: .
          ports:
           - 3306
          volumes:
           - ./data:/var/lib/mysql
           - ./conf:/etc/mysql/conf.d
           - /home/dump:/home/dump
          environment:
           - MYSQL_ALLOW_EMPTY_PASSWORD=yes
           - MYSQL_USER=dba
           - MYSQL_PASSWORD=123
           - TZ=Asia/Shanghai
           - LANG=C.UTF-8
           
    

    3.在服务器上进入到该目录,执行docker-compose build命令
    在这里插入图片描述
    如果报以下错误:Cannot open self /usr/local/bin/docker-compose or archive /usr/local/bin/docker-compose.pkg
    在这里插入图片描述
    这是因为官方文档中描述的方法(如下),安装时curl下载下来的文件是不完整的(可以把你从浏览器上下载下拉的docker-compose-Linux-x86_64文件的大小与你curl下载下拉的文件的大小做对比,如下图),而且没有给出任何错误信息,这可能是https的问题。

    curl -L https://github.com/docker/compose/releases/download/1.14.0-rc2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
    chmod +x /usr/local/bin/docker-compose
    

    在这里插入图片描述
    解决办法:

    进入下面的网址下载目前的最新版:
    
    https://github.com/docker/compose/releases/tag/1.14.0-rc2
    
    网页拉到最下面,下载:
    
    docker-compose-Linux-x86_64
    
    然后将文件上传到 /usr/local/bin/ 文件夹下,然后将其重命名为docker-compose,修改此文件的权限,增加可执行:chmod +x /usr/local/bin/docker-compose
    
    然后再运行 
    
    [root@fd240 bin]# docker-compose version
    docker-compose version 1.14.0-rc2, build 24dae73
    docker-py version: 2.3.0
    CPython version: 2.7.13
    OpenSSL version: OpenSSL 1.0.1t 3 May 2016
    
    可以看到已经没有问题了(如下图)。
    
    

    在这里插入图片描述

    4.启动mysql
    在这里插入图片描述
    5.进入mysql,账号密码在上面的docker-compose.yml中可以找到,我这里使用root账号登录,密码为空,进去创建一个数据库之后就导入数据。
    docker exec -it 容器id bash
    在这里插入图片描述

    部署Redis

    在服务器上新建一个用于部署redis的文件夹
    在这里插入图片描述
    在此文件夹下添加一下三个文件
    redis.conf

    bind 0.0.0.0
    protected-mode no
    port 6379
    tcp-backlog 511
    timeout 0
    tcp-keepalive 300
    
    ################################# GENERAL #####################################
    daemonize yes
    supervised no
    pidfile /var/run/redis_6379.pid
    loglevel notice
    logfile ""
    databases 2
    
    ################################ SNAPSHOTTING  ################################
    ave 1 1
    #save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename dump.rdb
    dir ./
    
    ################################# REPLICATION #################################
    slave-serve-stale-data yes
    slave-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-disable-tcp-nodelay no
    slave-priority 100
    
    ################################## SECURITY ###################################
    requirepass redis
    
    ################################### LIMITS ####################################
    maxclients 10000
    
    ############################## APPEND ONLY MODE ###############################
    appendonly yes
    appendfilename "appendonly.aof"
    # appendfsync always
    appendfsync everysec
    # appendfsync no
    no-appendfsync-on-rewrite no
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    aof-load-truncated yes
    
    ################################ LUA SCRIPTING  ###############################
    lua-time-limit 5000
    
    ################################ REDIS CLUSTER  ###############################
    cluster-enabled no
    
    ################################## SLOW LOG ###################################
    slowlog-log-slower-than 10000
    slowlog-max-len 128
    
    ################################ LATENCY MONITOR ##############################
    latency-monitor-threshold 0
    
    ############################# EVENT NOTIFICATION ##############################
    notify-keyspace-events ""
    
    ############################### ADVANCED CONFIG ###############################
    hash-max-ziplist-entries 512
    hash-max-ziplist-value 64
    list-max-ziplist-size -2
    list-compress-depth 0
    set-max-intset-entries 512
    zset-max-ziplist-entries 128
    zset-max-ziplist-value 64
    hll-sparse-max-bytes 3000
    activerehashing yes
    client-output-buffer-limit normal 0 0 0
    client-output-buffer-limit slave 256mb 64mb 60
    client-output-buffer-limit pubsub 32mb 8mb 60
    hz 10
    aof-rewrite-incremental-fsync yes
    

    Dockerfile

    #基础镜像
    FROM redis
    
    #将自定义conf文件拷入
    COPY ./redis.conf  /etc/redis/redis.conf
    
    #修复时区
    #RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    RUN echo 'Asia/Shanghai' >/etc/timezone
    
    # Redis客户端连接端口
    EXPOSE 6379
    
    #使用自定义conf启动
    CMD [ "redis-server", "/etc/redis/redis.conf" ]
    
    

    docker-compose.yml

    version: '2'
    
    services:
      redis:
        image: redis
        container_name: redis
        restart: always
        ports:
          - 6379:6379
        environment:
          - appendonly=yes # 打开redis密码设置
          - requirepass=123456 # 设置redis密码
        volumes:
          - ./redis.conf:/etc/redis/redis.conf
       # command: redis-server /etc/redis/redis.conf
    
    networks:
       default:
         external:
           name: master
    

    在服务器进入到当前目录,执行docker-compose build命令和docker-compose up -d命令
    在这里插入图片描述
    检查redis是否启动成功
    在这里插入图片描述

    部署Nginx

    1.在服务器上新建一个目录用于部署nginx
    在这里插入图片描述
    2.把以下三个文件拷贝到该目录下,并在该目录下新建一个cert文件夹
    在这里插入图片描述
    nginx.conf

    user  nginx;
    worker_processes  1;
    
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        keepalive_timeout  400;
        client_header_timeout 10m;
        client_body_timeout 10m;
        client_max_body_size 512m;
        client_header_buffer_size 16k;
        large_client_header_buffers 4 16k; 
    
        proxy_connect_timeout 300;
        proxy_read_timeout 300;
        proxy_send_timeout 300;
        proxy_buffer_size 64k;
        proxy_buffers   4 32k;
        proxy_busy_buffers_size 64k;
        proxy_temp_file_write_size 64k;
    
    
        sendfile        on;
        #tcp_nopush     on;
    
    
        #gzip  on;
    
        include /etc/nginx/conf.d/*.conf;
    }
    
    

    Dockerfile

    FROM nginx
    
    RUN mkdir -p /var/www
    
    COPY ./cert/ /etc/nginx/cert/
    
    EXPOSE 80 443
    
    CMD ["nginx","-g","daemon off;"]
    

    docker-compose.yml

    version: '2'
    
    networks:
      default:
        external:
          name: master
    
    services:
      nginx:
        image: nginx
        container_name: nginx
        restart: always
        build: .
        ports:
         - "80:80"
         - "443:443"
        volumes:
         - ./conf:/etc/nginx/conf.d
         - ./nginx.conf:/etc/nginx/nginx.conf:ro 
         - ./web:/var/www
        environment:
          TZ: Asia/Shanghai
    

    3.从服务器进入到该目录,执行docker-compose build命令和docker-compose up -d命令
    在这里插入图片描述

    nginx启动虽然没有报错,但是我们会发现nginx访问不了,我们可以进入到nginx容器,执行nginx -t命令检测一下我们的配置文件,会报以下错误
    在这里插入图片描述
    这里是一个坑,因为我是在window下使用notpad++编辑我这个quality_training.conf文件的,保存的时候自动使用了一种错误的编码格式,其实我们应该使用“无BOM格式编码”
    在这里插入图片描述
    然后我改为无BOM格式编码之后再执行一次nginx -t命令,报以下错误,这是因为我们配置了443端口的server,这是https对于的server,配置这个server是需要配置ssl证书的,要不你就配置证书(可以参考我的另外一篇文章https://blog.csdn.net/aimashi620/article/details/83056927),要不你就把这个server删掉。
    在这里插入图片描述
    在我配置证书的时候还报了“找不到证书”这个错误,这个时候可以重启容器再试一次就成功了(如果容器一直在重启中,执行docker rm -f 容器id,把容器删除掉再重新docker-compose build和docker-compose up -d)
    在这里插入图片描述

    域名配置

    1.登录阿里云控制台,进入域名管理控制台
    在这里插入图片描述
    2.点击解析
    在这里插入图片描述
    3.添加一条记录,把域名解析到我们新买的服务器上在这里插入图片描述
    在这里插入图片描述

    配置SSL证书

    参考我的另外一篇文章https://blog.csdn.net/aimashi620/article/details/83056927

    服务链接Mysql

    直接在服务器上用账号密码能够登录mysql,服务的mysql配置也没问题,但是访问就是报错。这里就需要注意一个问题了,你在服务器上使用mysql -u root -p 输入的这个密码虽然是可以正常的登录数据库,但是你在项目里配置的jdbc连接的密码可不一定是这一个,项目里配置的那个叫做mysql的远程连接密码,可以同过set password for root@’%’=password(’ 密码 ');命令进行设置。

    在这里插入图片描述
    然后把项目里的jdbc密码改成上面用set password for root@’%’=password(’ 密码 ');命令设置的密码,然后重新部署一次,访问成功
    在这里插入图片描述

    域名备案

    如果域名还没备案是无法进行访问的。查看域名是否已经备案可以通过此连接进行查询http://icp.chinaz.com/gdsxzlg.org.cn

    在这里插入图片描述

    微信小程序想要访问外部链接的配置流程

    https://mp.weixin.qq.com/wxopen/devprofile?action=get_profile&token=1049164222&lang=zh_CN
    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 前端工程化之部署

    千次阅读 2018-09-30 17:12:43
    部署简单来说就是将构建产出的代码部署到服务器上,在开发中我们通常的操作就是使用ftp将代码上传到服务器上固定目录下即可,所以这项工作在很多开发看起来是简单而又无聊的工作,这种部署方式从本质上来说没毛病,...

    前言
        部署简单来说就是将构建产出的代码部署到服务器上,在开发中我们通常的操作就是使用ftp将代码上传到服务器上固定目录下即可,所以这项工作在很多开发看起来是简单而又无聊的工作,这种部署方式从本质上来说没毛病,但是只适用于由少数人维护的规模较小的项目,如果这是个用户量庞大的产品,拥有多体系的技术团队,那么,我们在设计部署流程的时候就需要考虑许多其他的因素了,比如如何多人协作,提高部署效率,控制部署时的安全等等,这个时候就不再是一个简单的ftp上传代码这么简单了。

        要做到前端资源自动化部署首先需要的就是设计合适的部署流程,这个和前端项目的大小和部署的环境是有直接联系的,比如测试环境,准生产环境,生产环境,他们的部署流程差异是比较大的,一般测试环境我们开发人员可以随便造,准生产环境和生产环境就需要专门的运维人员,按照严格的发布流程来部署了,这个时候,我们开发人员一般只需要提供代码的仓库地址和版本号,其他的都交给类似jenkins这种集成化平台来进行统一集成,当然这里面可能需要用到一些脚本,比如我所在的公司每个项目中目录中都创建有一个文件夹里面全部是一些python脚本,用来给jenkis打包使用的,这里不是我们要讲的点,这里只提一下。

        前面提到了部署流程,规范的流程是保障事情有条不紊向前推进的基础,就像我们想去"浪漫的土耳其",那么我们就得首先办理护照,然后再购买机票,订酒店…然后去找土耳其小姐姐。其实我觉得首先还是得看看自己的钱包还剩多少和房贷还有多少没还。扯远了,回到前端自动化部署上来。在设计流程的时候我们需要考虑的三大因素:

    1. 快速部署
    2. 协同部署
    3. 保证部署安全

    下面就一步一步简单总结一下。


    快速部署

         前面提到的使用sftp工具这种简单粗暴的方式来上传构建好的前端代码到服务器,雖然也相对比較快速,但是手动部署和自动化部署毕竟level还是差很多的,就像坐绿皮車和坐高铁那档次还是有那么一点点的,所以我们需要用自动化部署来代替手动 ,这样一方面可以提高部署效率,另一方面开发人员可以少做一些他们以为的无用功,然后把时间多花点在改bug和写bug这种事上来。
    大多数开发在后期都需要频繁的将修改后的代码部署到服务器上去,这个时候我们原始的部署流程是:

    Created with Raphaël 2.2.0开始通过SSH登录服务器打开sftp图形化界面上传代码结束

    看起来简单 ,但是手动去重复这种机械化的工作,不免让人感到乏味。这个时候就需要用代码来帮我部署。下面讲解一下我自己在vue-cli的基础上实现的本地快速部署方案

    实现步骤:

    1. 配置需要部署的目标服务器信息
    2. 实现部署行为
    3. 实现命令行
    配置需要部署的目标服务器信息:

        在部署的时候我们需要做到目标服务器地址的信息可配置化,所以我在config目录下的index.js文件中增了服务器的相关配置项:

    {
     ...
     publish:{
          remoteDir:'/xxx/xxx/xxx/target',//远程上传目录(服务器)
          localSourcePath:"",//本地需要上传的资源路径(默认项目根目录下的dist文件夹)
          serverConfig:{//服务器验证信息
              host: '',
              username: '***',
              password: '***',
              algorithms: {
                  "kex": [
                    "diffie-hellman-group1-sha1",
                    "ecdh-sha2-nistp256",
                    "ecdh-sha2-nistp384",
                    "ecdh-sha2-nistp521",
                    "diffie-hellman-group-exchange-sha256",
                    "diffie-hellman-group14-sha1"
                  ],
                  "cipher": [
                    "3des-cbc",
                    "aes128-cbc",
                    "aes192-cbc",
                    "aes256-cbc",
                    "aes128-ctr",
                    "aes192-ctr",
                    "aes256-ctr",
                    "aes128-gcm@openssh.com",
                    "aes256-gcm@openssh.com",
                    "arcfour",
                    "arcfour128",
                    "arcfour256",
                    "blowfish-cbc",
                    "cast128-cbc",
                  ],
                  "serverHostKey": [
                    "ssh-rsa",
                    "ecdsa-sha2-nistp256",
                    "ecdsa-sha2-nistp384",
                    "ecdsa-sha2-nistp521"
                  ],
                  "hmac": [
                    "hmac-sha2-256",
                    "hmac-sha2-512",
                    "hmac-sha1"
                  ]
              }
          }
     }
    

    这里algorithms这个配置项主要是解决在使用node-ssh2模块连接目标服务器的时候出现的服务器和客户端 加密方式不一致的问题,如果你在使用node-ssh2模块时也可能会遇见相同的错误,所以把这个配置项加上就解决了。这里个配置项配置好后就不需要在改变了。其他的配置项基本都是需要部署的服务器信息。

    实现部署行为

        实现部署行为主要是基于sftp协议,这里使用到了node-ssh2中实现的sftp相关的方法。我在这里实现流程主要是分以下几步:

    1. 构建,压缩构建后的代码
    2. 通过node-ssh2连接目标服务器
    3. 通过node-ssh2中的sftp相关方法上传压缩文件,解压,删除压缩文件
    4. 上传失败时执行回滚操作

        大致的流程图:
    部署实现原理
    实现代码在build文件夹里面的publish.js

    const uploadBySftp = require("./modules/ssh.js");
    let config = require("../config/index.js");
    const path = require("path");
    const chalk = require("chalk");
    const ora = require("ora");
    async function startUpload(config){
          config = initOption(config);
          const localPath = config.publish.localSourcePath;
          const targetPath = config.publish.remoteDir;
          let desc =  "*******************************************\n"
                     +"***              开始部署               ***\n"
                     +"*******************************************\n"
        //1 压缩
        let localZipPath = await uploadBySftp.zipLocalFile(localPath,targetPath);
        //2 连接ssh
         let upload = new uploadBySftp(config.publish.serverConfig);
         await upload.connect();
         try {
                //3 上传文件
                let remotePath = await upload.startUploadFile(localZipPath,targetPath,true);
                //4 解压
                let remoteZipPath = await upload.unzipRemoteFile(remotePath,targetPath,false);
                //5 删除远程压缩文件
                await upload.deleteZipFile(remoteZipPath);
                //删除原先已经存在的文件夹
                await upload.deleteFolder(upload.newName);
                let desc =  "\n******************************************\n"
                            +"***              部署成功              ***\n"
                           +"******************************************\n"
                console.log(chalk.green(desc));
         
         } catch (error) {
                console.error(chalk.red("文件部署失败"));
                await upload.rolUp();//开始回滚
         }
         //关闭连接
         upload.close();
    }
    /**
     * 初始化参数
     */
    function initOption(config){
       let hostPattern = /(?:(?:(?:25[0-5]|2[0-4]\d|(?:(?:1\d{2})|(?:[1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|(?:(?:1\d{2})|(?:[1-9]?\d))))/ig;
       let remoteHost = process.argv[2];
       let dirPattern = /(\/opt\/dss\/client\/){1}/ig
       let dir = process.argv[3];
      if(remoteHost){
        if(hostPattern.test(remoteHost)){
          config.publish.serverConfig.host = remoteHost;
        }
      }
    
       if(dir){
          config.publish.remoteDir = path.join(path.dirname(config.publish.remoteDir),dir).split(path.sep).join("/");
          console.log(config.publish.remoteDir);
       }
       //校验输出地址是否合法
       if(!dirPattern.test(config.publish.remoteDir)){
          throw new Error("上传地址非法");
          return
      }
       if(config.publish){
          if(!config.publish.remoteDir){
            throw new Error("请配置远程文件夹地址")
            return
          }
    
          if(!config.publish.localSourcePath){
              config.publish.localSourcePath = path.join(process.cwd(),"dist");
          }
    
          if(!config.publish.serverConfig.host||!config.publish.serverConfig.username||!config.publish.serverConfig.password){
            throw new Error("请配置远程服务器信息")
            return
          }
    
          return config;
       }else{
          return;
       }
    };
    startUpload(config);
    

    这里没有实现代码构建,这是因为vue-cli构建的vue项目已经幫我们实现了,只需要在npm run build之后执行这个部署操作就OK了,在后面实现发布命令的时候再讲;
    initOption方法主要时为了对服务器配置信息进行校验。

        具体的方法实现在build/modules/ssh.js里面

    实现命令行

        在使用vue-cli构建的项目中,我们可以使用npm run dev来启动本地开发环境,npm run build构建输出代码,这里我们实现一个npm run publish命令来实现部署本地代码到服务器的操作。首先需要在项目根目录下的package.json中新增npm run publish命令

     {
      ...
      "scripts":{
        ...
        "publish""npm run build&&node ./publish.js"
      }
     }
    

    配置完之后,我们就可以使用

    npm run publish
    

    来实现快速部署了,在运行命令前我们需要要不正配置文件中服务器的相关信息已经配置完成。这在一定程度上降低了我们部署的灵活性,在真实开发中我们一般不只有一台测试换服务器,有时候我们需要向不同的服务器部署,这时候就需要去改变配置参数,显得有点麻烦。所以这里新增了命令行注入参数的方式,来实现灵活部署,例如:

    1. npm run publish 172.25.20.xxx 实现向不同的服务器来部署代码
    2. npm run publish 172.25.20.xxx dirname 实现不是到服务器上某个文件夹里面面去。

    这样我们就可以在在开发中是先快速的向服务器部署了。
        快速部署其实就是将上面的手动上传代码变成了用程序来帮助我们实现上传,但是本质上还是一个简单的代码上传和替换,这只适合在本地开发环境到开发测试环境的部署,并且只适合单人或极少数人维护和技术体系简单的前端项目。如果是前端结构复杂,技术团队众多的前端项目,就需要考虑协同部署了。


    协同部署

        协同部署主要是解决多人同时开发的问题,因为你提交代码后会覆盖别人的代码,导致别人开发的功能模块失效。这个时候,就需要一个统一的管理平台来执行部署

    在这里插入图片描述

    从流程图上可以看出,协同部署需要统一管理平台来实现统一部署,当所有开发人员都提交版本后,这个时候在平台上触发打包部署,然后就可以继续去写bug了…。当然,统一管理平台会消耗一定的资源,所以需要根据项目自身的情况来决定了是否使用了,不过现在云管理平台已经非常普遍了,所以使用起来也是非常方便和简单的。

    安全部署

        简单来说就是需要保证部署操作的安全,避免误操作。就比如前一段时间阿里云宕机事件,据说就是某个"实习生"错误的执行了delete脚本,导致用户无法登陆,这种影响可想而知。当然我们前端部署不会涉及到对用户数据的操作,最严重的就是页面无法访问,恢复起来也是相对容易。但是这不是我们不重视前端安全部署的理由,比如那天一觉醒来天猫的页面无法访问了那问题就大条了。当然这对广大已婚男士来说可能这就是福音了,媳妇儿可以消停一下了。但是作为开发来说这就是严重的事故了,前两天顺丰程序猿误操作事件可以了解一下。所以在进行部署的时候一定要考虑到安全,要做到安全部署主要从三个方面下手,一方面是部署权限,另一方面就是有专门的人员负责审核部署请求,最后就是版本回退。

    部署权限

        正常情况下生产环境都是由专门的运维人员负责部署,我们开发人员就不需要吓操那份心了,最多就是熬夜打辅助,站在他们旁边陪着他们部署。至于运维人员那边怎么实现安全部署,我就不知道了。下面我们主要说一下准生产环境和开发测试环境的部署。

    部署请求审核

        准生产环境也叫仿真环境,对于我们开发来说它就是生产环境,它的部署流程也是要严格按照生产环境的部署要求来。通常情况下发起部署请求后,需要专门的人员来审核你的部署请求是否合理合法,只有请求通过后才能执行部署,这里需要专门的审核人员,这个人一般是经验非常丰富的开发人员,有可能就是我们常说的大牛。当然要是最后出了问题,他也是要陪你一起背锅的…。

    版本回退

        说完了前面部署权限和部署审核后下面就来说所版本回退,一般当你使用到版本回退的时候,也基本上宣布你这次部署失败了,部署失败意味着可能又要多加几个班了。版本回退一般是在升级的时候用到的。回退一方面是在部署后发现有严重bug的时候,需要回退到之前的稳定版本;保证生产正常;另一种情况就是在自动化部署过程中发生错误了,部署无法继续进行,需要回退到上一个版本。要做到回退关键就是需要在部署前对上一个版本在进行备份,所以第一次发版就不存在什么回退了,因为无路可退,没有上一个版本怎么回退呢。
        这里就拿我自己实现的本地自动部署方案说一下,因为我的部署对象是开发测试环境,所以安全性就要低的多,一方面对部署的地址进行校验,因为在部署的过程中需要对服务器上存在的相同路径文件进行重命名,为了防止错误的将其他重要文件重命名所以我们一般将上传的路径是固定的,因为代码在服务器上位置是固定了的,在上传的时候校验一下,有没有输入非法路径。另一方面如果部署过程中失败,就执行回退操作。


    本地自动化部代码 github地址,有心兴趣的可以看看。


    总结

        这篇文章算是是在看了《前端工程化设计与实践》部署篇以后的一个简单总结记录吧,目前前端工程化的书籍不是太多,大多都是以博客的形式存在,讲的内容只集中在工程化的某个环节或者讲的比较粗线条,就像我这里只总结了一下部署,这只是工程化中的一角,后面我会结合书籍的讲解和自己的实践分享工程化的脚手架,构建…。如果有兴趣的朋友可以购买这本书来看看,我不是打广告,我作者没半毛钱关系,只是我看完一遍后对于前端工程化清楚的理解,书读三遍其义自见,我打算再读几遍,然后结合书中讲解运用到工作中来,毕竟实践是检验真理的唯一标准。好了,收工,还是那句话请忽略文中的"通假字"。明天是国庆节了,祝大家国庆快乐!祝祖国富强,繁荣!祝自己一切安好!

    展开全文
  • 项目开发的最后一公里:项目部署

    千次阅读 2020-04-26 11:35:50
    一、Nginx 部署 去Nginx官网找到下载链接: 在服务器下载并安装Nginx: wget http://nginx.org/download/nginx-1.17.10.tar.gz tar xf nginx-1.17.10.tar.gz cd nginx-1.17.10 安装依赖...

    Hello,我是 Alex 007,一个热爱计算机编程和硬件设计的小白,为啥是007呢?因为叫 Alex 的人太多了,再加上每天007的生活,Alex 007就诞生了。

    经过三个多星期的摧残,驾考暂时告一段落了,科二险过,科三因为违反了道路安全交通法第52条挂了,这回要等一个多月才能再考了,虽然有点失落,但终于有时间在家里敲敲代码了。
    今天呢,分享一下项目上线的最后一公里:项目部署,也就是将我们写好的项目发布,在互联网上可以访问到。

    环境:CentOS7 + Nginx + Python + Django + uwsgi + MySql

    一、Nginx 部署

    1. Nginx官网找到下载链接:
      在这里插入图片描述
    2. 在服务器下载并安装Nginx:
    wget http://nginx.org/download/nginx-1.17.10.tar.gz
    
    tar xf nginx-1.17.10.tar.gz
    
    cd nginx-1.17.10
    

    安装依赖:

    sudo yum -y install pcre-devel zlib-devel
    

    开始安装:

    ./configure
    
    sudo make && make install
    

    启动Nginx:

    sudo /usr/local/nginx/sbin/nginx
    

    访问服务器测试安装:

    在这里插入图片描述

    二、Python 安装

    我这个人比较懒啊,直接安装了一个Anaconda。

    Anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。

    里面所包含的Jupyter Notebook是数据挖掘领域中最热门的工具。(例如Kaggle竞赛)

    可以去清华大学开源软件镜像站中找到喜欢的Anaconda版本,这里以Anaconda3-5.3.1-Linux-x86_64安装为例。

    在这里插入图片描述

    复制下载地址,然后在Linux中使用wget下载:

    wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.3.1-Linux-x86_64.sh
    

    执行结果为:

    [Alex@Alex ~]$ wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.3.1-Linux-x86_64.sh
    --2020-03-30 10:23:04--  https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.3.1-Linux-x86_64.sh
    Resolving mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)... 101.6.8.193, 2402:f000:1:408:8100::1
    Connecting to mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)|101.6.8.193|:443... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 667976437 (637M) [application/octet-stream]
    Saving to: ‘Anaconda3-5.3.1-Linux-x86_64.sh’
    
    100%[=============================================================================================>] 667,976,437 10.4MB/s   in 65s
    
    2020-03-30 10:24:09 (9.75 MB/s) - ‘Anaconda3-5.3.1-Linux-x86_64.sh’ saved [667976437/667976437]
    

    在Linux里面.sh文件是可执行的脚本文件,需要用命令bash来进行安装:

    bash Anaconda3-5.3.1-Linux-x86_64.sh
    

    出现如下信息按 Enter:

    In order to continue the installation process, please review the license agreement.
    Please, press ENTER to continue
    >>>
    

    然后按几次空格翻页浏览一下license,

    出现如下信息输入 yes :

    Do you accept the license terms? [yes|no]
    [no] >>>yes
    

    之后选择anaconda的安装位置,可以直接按 Enter 使用默认位置:

    Anaconda3 will now be installed into this location:
    /home/Alex/anaconda3
    
      - Press ENTER to confirm the location
      - Press CTRL-C to abort the installation
      - Or specify a different location below
    
    [/home/Alex/anaconda3] >>>
    

    经过大概几分钟的安装,anaconda会帮我们安装好很多常用的第三方库。

    再之后会让我们初始化anaconda3,输入yes即可:

    Do you wish the installer to initialize Anaconda3
    in your /home/Alex/.bashrc ? [yes|no]
    [no] >>>yes
    

    最后让我们安装VSCode,这个我们暂时用不到,输入no:

    Visual Studio Code License: https://code.visualstudio.com/license
    
    Do you wish to proceed with the installation of Microsoft VSCode? [yes|no]
    >>>no
    

    这样,我们的Anaconda就安装好了:

    (base) [Alex@Alex ~]$ python
    Python 3.7.0 (default, Jun 28 2018, 13:15:42)
    [GCC 7.2.0] :: Anaconda, Inc. on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> exit()
    

    三、MySQL 安装

    1. 配置yum源

    下载mysql源安装包

    在MySQL官网中下载YUM源rpm安装包:http://dev.mysql.com/downloads/repo/yum/

    复制下载链接:https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm

    执行下载命令:

    wget https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
    

    安装mysql源

    下载完成后使用下面命令安装源:

    yum localinstall mysql80-community-release-el7-1.noarch.rpm
    

    检查是否安装成功

    yum repolist enabled | grep "mysql.*-community.*"
    

    1. 安装mysql

    直接使用命令:yum install mysql-community-server

    1. 启动mysql服务

    启动

    systemctl start mysqld
    

    或者

    service mysqld start
    

    查看启动状态

    systemctl status mysqld
    

    或者

    service mysqld status
    

    在这里插入图片描述
    设置开机启动

    systemctl enable mysqld
    systemctl daemon-reload
    
    1. 配置及部分命令

    修改登录密码

    mysql安装完成之后,在/var/log/mysqld.log文件中给root生成了一个默认密码。通过下面的方式找到root默认密码,然后登录mysql进行修改:

    grep 'temporary password' /var/log/mysqld.log
    

    在这里插入图片描述

    本地MySQL客户端登录

    mysql -uroot -p
    

    密码是上一步查询出来的。输入后回车。

    然后修改密码:

    ALTER USER 'root'@'localhost' IDENTIFIED BY 'TestBicon@123';
    

    或者

    set password for 'root'@'localhost'=password('TestBicon@123');
    

    注意:mysql5.7默认安装了密码安全检查插件(validate_password),默认密码检查策略要求密码必须包含:大小写字母、数字和特殊符号,并且长度不能少于8位。否则会提示ERROR 1819 (HY000): Your password does not satisfy the current policy requirements错误,如下图所示:

    通过msyql环境变量可以查看密码策略的相关信息(执行这一步需要先修改默认密码,即执行完上一步修改才可以,否则会报错:ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.)

    show variables like '%password%';
    

    validate_password_policy:密码策略,默认为MEDIUM策略

    validate_password_dictionary_file:密码策略文件,策略为STRONG才需要

    validate_password_length:密码最少长度

    validate_password_mixed_case_count:大小写字符长度,至少1个

    validate_password_number_count :数字至少1个

    validate_password_special_char_count:特殊字符至少1个

    上述参数是默认策略MEDIUM的密码检查规则。

    修改密码策略:

    在/etc/my.cnf文件添加validate_password_policy配置,指定密码策略:

    选择0(LOW),1(MEDIUM),2(STRONG)其中一种,选择2需要提供密码字典文件。

    validate_password_policy=0

    如果不需要密码策略,添加my.cnf文件中添加如下配置禁用即可:

    validate_password = off

    重新启动mysql服务使配置生效:systemctl restart mysqld

    添加远程登录用户

    默认只允许root帐户在本地登录,如果要在其它机器上连接mysql,必须修改root允许远程连接,或者添加一个允许远程连接的帐户。

    修改root用户远程访问权限:

    选择 mysql 数据库:use mysql;

    在 mysql 数据库的 user 表中查看当前 root 用户的相关信息:

    select host, user from user;
    

    查看表格中 root 用户的 host,默认应该显示的 localhost,只支持本地访问,不允许远程访问。

    授权 root 用户的所有权限并设置远程访问

    GRANT ALL ON *.* TO 'root'@'%';
    

    如果报错:ERROR 1410 (42000): You are not allowed to create a user with GRANT

    则使用:

    update user set host='%' where user ='root';
    

    然后使用下面命令使修改生效:

    flush privileges;
    

    如有需要再执行之前授权报错的命令即可成功,最后同样使用flush privileges;命令刷新。

    sqlyog链接时出现2058异常

    完成上面的配置使用sqlyog链接时会出现2058的异常,此时我们需要修改mysql,命令行登录mysql(与修改密码中登录相同,使用修改后的密码),然后执行下面的命令:

    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

    其中password为自己修改的密码。然后SQLyog中重新连接,则可连接成功,OK。

    如果报错:ERROR 1396 (HY000): Operation ALTER USER failed for 'root'@'localhost'则使用下面命令:

    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

    修改默认编码方式

    mysql8.0默认编码方式为utf8mb4,因此使用时不需要修改,可使用如下命令查看:

    SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';

    如果需要修改其他编码方式,方法有很多,以下仅为举例。

    比如需要修改为utf8mb4,可以使用如下方式:

    修改mysql配置文件my.cnf(windows为my.ini)

    my.cnf一般在etc/mysql/my.cnf位置。找到后请在以下三部分里添加如下内容:

    [client]
    
    default-character-set = utf8mb4
    
    [mysql]
    
    default-character-set = utf8mb4
    
    [mysqld]
    
    character-set-client-handshake = FALSE
    
    character-set-server = utf8mb4
    
    collation-server = utf8mb4_unicode_ci
    
    init_connect='SET NAMES utf8mb4'
    

    重启mysql即可。

    collation_connection 、collation_database 、collation_server是什么没关系。但必须保证以下这几个变量必须是utf8mb4。:

    • character_set_client  (客户端来源数据使用的字符集)
    • character_set_connection     (连接层字符集)
    • character_set_database   (当前选中数据库的默认字符集)
    • character_set_results (查询结果字符集)
    • character_set_server (默认的内部操作字符集)

    数据库连接参数中:

    characterEncoding=utf8会被自动识别为utf8mb4,也可以不加这个参数,会自动检测。

    而autoReconnect=true是必须加上的。

    部分参数配置查询命令

    #查询mysql最大连接数设置

    show global variables like 'max_conn%';

    SELECT @@MAX_CONNECTIONS AS 'Max Connections';

    # 查看最大链接数

    show global status like 'Max_used_connections';

    # 查看慢查询日志是否开启以及日志位置

    show variables like 'slow_query%';

    # 查看慢查询日志超时记录时间

    show variables like 'long_query_time';

    # 查看链接创建以及现在正在链接数

    show status like 'Threads%';

    # 查看数据库当前链接

    show processlist;

    # 查看数据库配置

    show variables like '%quer%';

    四、部署发布平台

    1. clone代码

    从GitHub上将项目下载下来:

    git clone https://github.com/koking0/MatrixStudioManagementSystem.git 
    
    1. 搭建虚拟环境

    虚拟环境相当于一个抽屉(或文件夹),在这个抽屉(或文件夹)中安装的任何软件包都不会影响到其他抽屉(或文件夹)。

    并且在项目中,我可以指定这个项目的虚拟环境来配合我的项目。

    比如我们现在有一个项目是基于 Django1.10.x 版本,又有一个项目是基于 Django 2.0.x 的版本,那么这时候就可以创建两个虚拟环境,在这两个虚拟环境中分别安装 Django 1.10.x 和 Django 2.0.x 来适配我们的项目。

    一句话,虚拟环境解决多版本共存问题;

    安装虚拟环境

    sudo pip install virtualenv
    

    创建虚拟环境

    conda create -n venv python=3.7
    

    启动虚拟环境

    conda activate venv
    
    1. 安装Django
    pip install django
    
    1. 安装uwsgi
    pip install uwsgi
    
    1. 配置uwsgi
    vim uwsgi.ini
    

    文件内容如下:

    [uwsgi]                                                          
    #socket 绑定的IP and port                                           
    socket = 127.0.0.1:8080                                          
    #主进程                                                             
    master = true                                                    
    #多站模式                                                            
    vhost = true                                                     
    #多站模式时不设置入口模块和文件                                                 
    no-site = true                                                   
    #子进程数量                                                           
    workers = 2                                                      
    #                                                                
    reload-mercy = 10                                                
    #退出、重启时清理文件                                                      
    vacuum = true                                                    
    #最大请求数                                                           
    max-requests = 1000                                              
    #                                                                
    limit-as = 512                                                   
    #buffer 大小                                                       
    buffer-size = 30000                                              
    #pid 文件                                                          
    pidfile = /var/run/uwsgi.pid                                     
    #日志文件                                                            
    daemonize = /var/log/uwsgi.log                                   
                                                                     
    pythonpath = /root/Matrix工作室管理系统/venv/lib/python3.7/site-packages
    
    1. 启动uwsgi
    uwsgi --ini /etc/uwsgi/uwsgi.ini
    

    如果报错:uwsgi: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory

    这是由于openssl库的位置不正确造成的,我们可以先通过如下命令找到libssl.so.1.1

    find / -name libssl.so.1.1
    

    执行结果如下:

    [root@Alex ~]# find / -name libssl.so.1.1
    /root/anaconda3/pkgs/openssl-1.1.1g-h7b6447c_0/lib/libssl.so.1.1
    /root/anaconda3/lib/libssl.so.1.1
    

    然后创建软链接:

    ln -s /root/anaconda3/lib/libssl.so.1.1 /lib64/libssl.so.1.1
    

    还可能遇到的报错,解决方案类似:

    [root@Alex ~]# uwsgi --ini /etc/uwsgi/uwsgi.ini
    uwsgi: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory
    [root@Alex ~]# find / -name libssl.so.1.1
    /root/anaconda3/pkgs/openssl-1.1.1g-h7b6447c_0/lib/libssl.so.1.1
    /root/anaconda3/lib/libssl.so.1.1
    [root@Alex ~]# ln -s /root/anaconda3/lib/libssl.so.1.1 /lib64/libssl.so.1.1
    [root@Alex ~]# uwsgi --ini /etc/uwsgi/uwsgi.ini
    uwsgi: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory
    [root@Alex ~]# find / -name libcrypto.so.1.1
    /root/anaconda3/pkgs/openssl-1.1.1g-h7b6447c_0/lib/libcrypto.so.1.1
    /root/anaconda3/lib/libcrypto.so.1.1
    [root@Alex ~]# ln -s root/anaconda3/lib/libcrypto.so.1.1 /lib64/libcrypto.so.1.1
    [root@Alex ~]# uwsgi --ini /etc/uwsgi/uwsgi.ini
    uwsgi: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory
    [root@Alex ~]# ln -s /root/anaconda3/lib/libcrypto.so.1.1 /lib64/libcrypto.so.1.1
    [root@Alex ~]# uwsgi --ini /etc/uwsgi/uwsgi.ini
    uwsgi: error while loading shared libraries: libicui18n.so.58: cannot open shared object file: No such file or directory
    [root@Alex ~]# find / -name libicui18n*
    /usr/lib64/libicui18n.so
    /usr/lib64/libicui18n.so.50.1.2
    /usr/lib64/libicui18n.so.50
    /root/anaconda3/pkgs/icu-58.2-h9c2bf20_1/lib/libicui18n.so
    /root/anaconda3/pkgs/icu-58.2-h9c2bf20_1/lib/libicui18n.so.58
    /root/anaconda3/pkgs/icu-58.2-h9c2bf20_1/lib/libicui18n.so.58.2
    /root/anaconda3/pkgs/icu-58.2-h9c2bf20_1/lib/libicui18n.a
    /root/anaconda3/lib/libicui18n.so
    /root/anaconda3/lib/libicui18n.so.58
    /root/anaconda3/lib/libicui18n.so.58.2
    /root/anaconda3/lib/libicui18n.a
    [root@Alex ~]# ln -s /root/anaconda3/lib/libicui18n.so.58 /lib64/libicui18n.so.58
    [root@Alex ~]# ln -s /root/anaconda3/lib/libicuuc.so.58 /lib64/libicuuc.so.58
    [root@Alex ~]# ln -s /root/anaconda3/lib/libicudata.so.58 /lib64/libicudata.so.58
    

    显示 [uWSGI] getting INI configuration from uwsgi.ini 表明uwsgi运行成功。

    可以查看一下:

    (base) [root@Alex ~]# netstat -ntpl
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 127.0.0.1:9090          0.0.0.0:*               LISTEN      18739/uwsgi
    tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      6194/nginx: master
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      8162/sshd
    tcp        0      0 0.0.0.0:8888            0.0.0.0:*               LISTEN      1154/python
    tcp6       0      0 :::33060                :::*                    LISTEN      1811/mysqld
    tcp6       0      0 :::3306                 :::*                    LISTEN      1811/mysqld
    
    1. 处理Django静态文件

    在开发中处理网站的css js image等静态文件,不用顾及性能,安全的问题,交给Django内部处理好了。

    但如果正式部署到服务器的时候,这样的配置就会影响到性能和安全性了,因此静态文件要交由Nginx处理。

    首先在项目的settings.py文件中设置参数:

    STATIC_ROOT= '/opt/static' 
    

    然后使用命令手机Django的静态文件:

    python manage.py collectstatic
    

    这样就可以将项目中使用的静态文件收集在一起,可以通过如下命令查看:

    python manage.py collectstatic
    
    1. 配置Nginx
    vim /usr/local/nginx/conf/nginx.conf
    

    文件内容如下:

    worker_processes  1;                                                            
                                                                                    
    error_log  logs/error.log;                                                      
    error_log  logs/error.log  notice;                                              
    error_log  logs/error.log  info;                                                
                                                                                    
    pid        logs/nginx.pid;                                                      
                                                                                    
    events {                                                                        
        worker_connections  1024;                                                   
    }                                                                               
                                                                                    
                                                                                    
    http {                                                                          
        include       mime.types;                                                   
        default_type  application/octet-stream;                                     
                                                                                    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '   
                          '$status $body_bytes_sent "$http_referer" '               
                          '"$http_user_agent" "$http_x_forwarded_for"';             
                                                                                    
        access_log  logs/access.log  main;                                          
                                                                                    
        sendfile        on;                                                         
                                                                                    
        keepalive_timeout  65;                                                      
                                                                                    
        server {                                                                    
            listen       80;                                                        
            server_name  localhost;
            location / {                                                
                    include  uwsgi_params;                              
                    uwsgi_pass  127.0.0.1:8080;                         
                    uwsgi_param UWSGI_SCRIPT Matrix工作室管理系统.wsgi;        
                    uwsgi_param UWSGI_CHDIR  /root/Matrix工作室管理系统;       
                    index  index.html index.htm;                        
                    client_max_body_size 35m;                           
            }                                                           
            location /static {                                          
                    alias /opt/static;                                  
            }                                                           
        }                                                               
    }                                                                   
    

    五、测试

    到此为止,我们的项目算是部署完成了,可以在自己的浏览器上访问一下看看:
    在这里插入图片描述
    好了,项目上线就完成了,接下来可以通过JMeter测试最大并发请求数:

    100个线程:
    在这里插入图片描述
    在这里插入图片描述

    1000个线程:
    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 部署测试环境(我举的例子是aix系统的,哈哈,现在都是linux了,不过我觉得都是异曲同工吧) 测试工程部署路径(根据你们的项目定路径就可以啦) /home/webuser/tomcat/webapps/test 部署操作步骤 (1) 输入账号...
  • 安装部署配置 1. 声明 1.1 关于环境 在您使用Galaxybase开发者版本之前,请确保您的运行环境满足 软硬件配置需求 Galaxybase的开发者版本依赖于docker环境 1.2 关于用户权限 为了适配更多的离线环境,Galaxybase...
  • 部署服务器

    万次阅读 多人点赞 2018-09-11 18:49:47
    早些日子想着搭建自己的一台服务器,奈何各方面的因素使之悬而未决,今有幸有机会动手操作一番,想着将其记录下来,方便暴露出问题,还望各路大神多多指点 一,购买服务器 ...   1,本次只是一次练手并不做后期...
  • 如何部署软件

    2016-06-28 20:20:23
    让我们来聊聊部署 无论你何时对自己的代码库做出改动,总会伴随着要破坏一些东西的风险。 没有人喜欢宕机, 没有人喜欢暴躁的用户, 也没有人喜欢生气的经理,所以部署新代码到生产环境变成颇具压力的一个环节。 你...
  • 几种部署方式整理

    千次阅读 2019-01-15 14:14:00
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • 环境配置 在正式安装 Hexo 之前,我们需要确认电脑中是否已安装下列应用程序: ... Node.js 详情安装教程 查看Node版本:node -v ...打开git的.ssh目录(我的是C:\Users\Administrator.ssh),然后右键git bash如下图: ...
  • jenkins之搭建部署

    万次阅读 2019-05-29 18:07:27
    25.1 CI/CD介绍 互联网软件的开发和发布,已经形成了一套标准流程,假如把开发工作流程...正如你在上图中看到,[持续集成(Continuous Integration)]、[持续交付(Continuous Delivery)]和[持续部署(Continuous Depl...
  • web项目如何部署到服务器?

    万次阅读 2018-08-07 21:32:03
    写好上位机程序后,如何部署到服务器? (这里我用的是tomcat服务器) 首先说明一点:为了程序测试是否连接到下位机,我编写了一个命名为gprs的java文件,这个可以用下位机连接是否成功。程序见附录,下面说具体的...
  • Linux系统(Centos)安装tomcat和部署Web项目

    万次阅读 多人点赞 2019-01-01 15:34:03
    文章结构 1.准备工作 2.在Linux下安装Tomcat8.0 3.Linux中配置tomcat的服务器启动和关闭和配置tomcat的开机启动 ...5.使用IDEA打包Maven托管的WEB项目 6.将JavaWeb项目发布到Tomcat8.0下面并且访问展示 ...
  • SpringBoot 项目部署到服务器上(Jar包)

    万次阅读 多人点赞 2019-03-22 10:13:34
    1. 部署方式 Springboot 和普通web 应用程序不一样,其本质上是一个 Java 应用程序,那么又如何部署呢? 通常来说,Springboot 部署会采用两种方式:全部打包成一个jar,或者打包成一个war。现在讲一下打包成 jar ...
  • Jenkins自动构建部署项目到远程服务器

    万次阅读 多人点赞 2018-07-08 16:22:22
    1.下载jenkins 下载地址:https://jenkins.io/ 启动jenkins方式有2种 1.1切换到jenkins.war包的存放目录 启动命令: java -jar jenkins.war 启动jenkins 访问: localhost:8080 就能...
  • spring boot2 打成jar包并发布到Linux服务器(包含发布和取消发布) 关于打包方式各种方式都可以,具体方式包括idea自带的maven插件打包,或者命令打包,或者其他工具比如eclipse打包,这里默认你已经打包ok了,这里也是...
  • 关于将Web项目部署到阿里云服务器-5个步骤搞定

    万次阅读 多人点赞 2017-10-18 15:21:24
    1. 先登录阿里云网站注册账号,选择服务器类型(我用的是云服务器ECS), 如果你还是在读大学生可享受优惠价,最低好像是9.9元一月。之后勾选系统镜像。 2. 购买好之后登录阿里云控制台。 找到自己的云服务器...
  • 如果你不想用docker部署,想用源码安装 并且搭建集群请借鉴 (安装过程略)VMware利用3台Ubuntu搭建MySQL集群服务器 在当前的IT 环境下 docker部署成为了一种潮流 在正式进入docker安装PXC集群前的小故事 源码 ...
  • spring boot 项目部署服务器 两种方式

    万次阅读 多人点赞 2018-08-08 13:05:46
    Spring Boot 两种部署服务器的方式 jar包 jar包方式启动,也就是使用spring boot内置的tomcat运行。服务器上面只要你配置了jdk1.8及以上,就ok。不需要外置tomcat 1.打成jar包 2.将jar包放到任意目录,执行...
  • springboot部署到阿里云linux服务器
  • SpringBoot项目的云服务器部署

    万次阅读 多人点赞 2017-06-10 22:03:43
    怎么把springboot工程部署到云服务器上呢?可能有人会说,博主你前篇不是讲了java工程的云部署把;但是我想澄清一点的是,我前篇的工程都是ssm框架搭建的,而springboot可是自带tomcat喽!这就有点麻烦....淡定,往...
  • nginx服务器搭建及部署项目流程

    万次阅读 2015-12-25 11:23:56
    二、需要在已安装的产品项目服务器上打包3个文件下来,用以到其他服务器的安装,操作如下:(以125.211.221.244服务器为例) 1、进入命令行,到/opt 目录下将tomcat打包 [root@ybl02 ~]# cd /opt [root@ybl02 opt]# ...
  • hexo-to-your-server 一、完成效果 ... 二、准备 基本上每一步都会给出...通过Git将Hexo博客部署服务器 可以使用官方的node安装包,也可以使用nvm管理 node 版本,但千万不要混用,不然会环境和管理上的麻烦 ...
  • 部署Django到阿里云服务器教程

    万次阅读 多人点赞 2018-05-30 13:57:03
    部署Django到阿里云服务器教程 基于Ubuntu16.04 + Python3 + nginx + mysql + Django 接下来先安装这些必要的环境,这些操作都是在你已经购买了阿里云服务器。并且在本地你已经搭建好了Django博客。现在...
  • 资源:一台开发环境的服务器和一台线上环境的服务器。 软件:Xshell(linux运行环境) , fileZilla(linux文件传输工具) 功能:我们在开发环境中将项目由git中clone下来,建立开发分支,拉取开发分支进行程序的...
  • Jenkins自动打包并部署到远程服务器

    万次阅读 多人点赞 2019-02-01 10:30:18
    本文主要介绍了使用Jenkins自动打包到远程服务器。 一、Jenkins简介 Jenkins是一个开源软件项目,是基于Java开发的广泛用于持续构建的可视化web工具,就是各种项目的的“自动化”编译、打包、分发部署,将传统编译...
  • 很多朋友都认为微信小程序申请、部署、发布很难,需要很长时间。 实际上,微信和腾讯云同是腾讯产品,已经提供了10分钟(根据准备资源情况,已完成小程序申请认证)完成小程序开发、部署、发布的方式。当然,实现的...
  • 当在服务器部署多个tomcat时,存在端口号冲突的问题,所以需要修改tomcat配置文件server.xml。 首先了解下tomcat的几个主要端口: <Connector URIEncoding="UTF-8" connection...
  • vSphere是业界领先的服务器虚拟化软件,是现代SDDC的核心,可帮助您在跨云的通用操作环境中运行,管理,连接和保护应用程序。 新的高级安全功能完全集成到虚拟机管理程序中,并由机器学习提供支持,可为安全事件...
  • 其实就是花钱买块区域,服务器,域名,云解析,花了好多money。。。 一、租服务器 百度搜索阿里云 进入官网首页,点击登录 进入登录页面,可以使用邮箱登录或者注册 进入注册页面,填写注册信息 登录成功,进入...

空空如也

1 2 3 4 5 ... 20
收藏数 5,810,048
精华内容 2,324,019
关键字:

部署