• 项目部署流程


    项目部署

    http://blog.51cto.com/ljmict

    项目部署流程:

    1. 买服务器, 服务器租用

    2. 选择操作系统的版本,安装系统

    3. 在开发环境中把项目需要的pip包写到一个文件 pip freeze . requirements

      .txt

    4. 把项目上传到服务器

    5. 部署项目, 安装需要的环境

      1. pyhton3解释器
      2. 虚拟环境
      3. 数据库
      4. nginx, uwsgi

    服务器

    nginx

    mysql

    redis

    uwsgi

    celery

    docker

    网站流量参考

    网站流量度量

    pv:独立访客

    ip:独立ip

    uv:独立访客

    并发:

    每秒响应的最大连接数

    web服务器每秒能够接受的用户连接数

    web服务器每秒能接受最大用户连接数

    web服务器单位时间能够处理的最大连接数

    Django前后端分离项目部署

    介绍

    技术栈 Nginx+uwsgi+celery+supervisor

    本教程 实现了负载均衡、反向代理、动静分离,还实现了根据客户端设备user-agent进行转发,也就是移动端和PC端访问的页面不一样。

    前期准备

    1. 项目部署逻辑图

    2. 环境准备

    服务器:6台VM
    操作系统:CentOS7
    LB、www、wap:安装Nginx
    uwsgi1、uwsgi2:安装nfs-utils、Python3解释器、virtualenv
    NFS:安装NFS
    MRCS:安装MySQL、Redis、virtualenv

    CentOS安装Nginx

    镜像下载地址 http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1804.iso

    CentOS 服务器部署遇到的常见问题

    CentOS不能联网

    进入目录

    cd /etc/sysconfig/network-scripts/
    

    输入ls查看文件列表, 找到网卡配置文件,如下图,我虚拟机的网卡名称为ens33

    编辑

    vi 
    

    按i进入编辑模式, 编辑ifcfg-ens33文件的最后一行,将ONBOOT=no改为ONBOOT=yes,

    按esc退出编辑模式, 输入:wq保存退出

    重启network:

    $ server network restart
    

    pingi下百度能不能ping通

    $ ping www.baidu.com
    

    如果能ping通, 说明网络已经可以连接了

    CentOS没有ifconfig命令的解决办法

    全新安装centos的时候,运行ifconfig准备查看服务器IP的时候, 发现会报错

    -bash:command not found
    

    网上搜了下, 原因可能是最小化安装centos等Linux发行版的时候会默认不安装ifconfig等命令

    解决的办法: yum安装ifconfig这个包

    首先搜索下

    $  yum search ifconfig
    

    发现ifconfig所属的命令包是net-tools.x86_64

    安装

    $ yum install net-tools.x86_64
    

    中途会询问“Is this os [y/d/n]”,按y回车,Complete完成安装。

    安装完之后就可以输入ifconfig查看网卡信息了

    CentOS修改终端输出语言

    远程连接centos服务器的时候, 发现有些字符会乱码

    在网上搜了下, 发现是默认语言设置的问题. 输入echo $LANGlocale查询, 结果如下

    修改默认语言, 编辑配置文件

    $ vi /etc/locale.conf
    

    添加下面字段, wq保存

    LANG=”zh_CN.UTF-8”
    

    应用配置文件, 使其生效

    $ source /etc/locale.conf
    

    问题解决

    CentOS编译安装Nginx

    1. 环境准备

    # 更换YUM源,centos默认源是国外的网站,下载会比较慢
    curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
    yum makecache
    # 安装编译环境,如果安装过了,就不需要再安装了
    yum -y install gcc*
    

    2. 安装pcre库,如果不安装pcre库,Nginx无法使用rewrite模块,在编译安装过程也会报错

    # 查询pcre库是否安装
    rpm -qa|grep pcre 
    yum -y install pcre pcre-devel
    # 安装完之后查询一下是否安装成功,如果能够看到pcre和pcre-devel包就可以了
    rpm -qa|grep pcre
    

    3. 安装nginx

    # 创建一个software/目录用来放软件包
    mkdir -p /opt/software
    # 创建安装目录
    mkdir -p /application/nginx-1.14.0
    # 下载nginx安装包
    cd /opt/software
    wget -q http://nginx.org/download/nginx-1.14.0.tar.gz
    # 创建一个nginx用户
    useradd nginx -s /sbin/nologin -M //创建一个nginx用户
    # 解压
    tar xvf nginx-1.14.0.tar.gz
    cd nginx-1.14.0
    # 安装
    ./configure --user=nginx --group=nginx --prefix=/application/nginx-1.14.0 --with-http_stub_status_module --with-http_ssl_module
    # 如果安装报./configure: error: SSL modules require the OpenSSL library 需要安装openssl-devel,安装完之后再执行一下上一条命令
    yum -y install openssl-devel
    make && make install
    # 创建软链接是为了以后如果要升级,应用程序中如果有引用Nginx路径,不需要做任何更改,访问的还是原来的路径/application/nginx
    ln -s /application/nginx-1.14.0/ /application/nginx 
    # 查看链接状态
    ls -l /application/nginx 
    

    注意:编译安装Nginx软件时,还可以使用./configure --help查看相关参数帮助

    4. 检查安装结果

    # 启动nginx服务
    /application/nginx/sbin/nginx
    netstat -lntup|grep 80 
    

    5. 在浏览器里面输入nginx服务器IP地址

    发现并没有成功,原因是被centos防火墙拦截了, 这个时候, 我们需要关闭防火墙

    6. 关闭防火墙

    CentOS7版本后防火墙默认使用firewalld,因此在CentOS7中关闭防火墙使用以下命令,

    # 临时关闭
    $ systemctl stop firewalld
    # 禁止开机启动
    $ systemctl disable firewalld
    Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
    Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.123456
    

    当然,如果安装了iptables-service,也可以使用下面的命令,

    $ yum install -y iptables-services
    # 关闭防火墙
    $ service iptables stop
    Redirecting to /bin/systemctl stop  iptables.service
    # 检查防火墙状态
    $ service iptables status
    Redirecting to /bin/systemctl status  iptables.service
    iptables.service - IPv4 firewall with iptables
       Loaded: loaded (/usr/lib/systemd/system/iptables.service; disabled; vendor preset: disabled)
       Active: inactive (dead)
    

    重新访问就能成功访问了

    CentOS 安装NFS服务

    0.准备工作

    在之前安装好的服务器克隆一个副本

    先把CentOS关机, 然后如图所示, 创建完整的克隆, 克隆一个副本

    安装NFS服务,需要安装nfs-utils和rpcbind,NFS的RPC服务,在Centos5.X下名称为portmap,在Centos6.X下名称为rcpbind。

    1.查询nfs服务和rpc服务是否安装

    [root@localhost ~]# rpm -qa|grep nfs 
    [root@localhost ~]# rpm -qa|grep rpcbind
    

    2.使用YUM安装nfs和rpcbind

    [root@localhost ~]# yum install -y nfs-utils
    

    3.启动nfs服务,在启动nfs服务之前,一定要先启动rpcbind,然后再启动nfs

    [root@localhost ~]# service rpcbind start
    Redirecting to /bin/systemctl start rpcbind.service
    
    

    查看rpc信息

    [root@localhost ~]# rpcinfo -p localhost 
       program vers proto   port  service
        100000    4   tcp    111  portmapper
        100000    3   tcp    111  portmapper
        100000    2   tcp    111  portmapper
        100000    4   udp    111  portmapper
        100000    3   udp    111  portmapper
        100000    2   udp    111  portmapper
    
    [root@localhost ~]# service nfs start 
    Starting NFS services:                                     [  OK  ]
    Starting NFS quotas:                                       [  OK  ]
    Starting NFS mountd:                                       [  OK  ]
    Starting NFS daemon:                                       [  OK  ]
    Starting RPC idmapd:                                       [  OK  ]
    

    启动nfs服务以后,再查看rpcinfo信息。

    [root@localhost ~]# rpcinfo -p
       program vers proto   port  service
        100000    4   tcp    111  portmapper
        100000    3   tcp    111  portmapper
        100000    2   tcp    111  portmapper
        100000    4   udp    111  portmapper
        100000    3   udp    111  portmapper
        100000    2   udp    111  portmapper
        100011    1   udp    875  rquotad
        100011    2   udp    875  rquotad
        100011    1   tcp    875  rquotad
        100011    2   tcp    875  rquotad
        100005    1   udp  35606  mountd
        100005    1   tcp  38238  mountd
        100005    2   udp  33761  mountd
        100005    2   tcp  41083  mountd
        100005    3   udp  47608  mountd
        100005    3   tcp  35056  mountd
        100003    2   tcp   2049  nfs
        100003    3   tcp   2049  nfs
        100003    4   tcp   2049  nfs
        100227    2   tcp   2049  nfs_acl
        100227    3   tcp   2049  nfs_acl
        100003    2   udp   2049  nfs
        100003    3   udp   2049  nfs
        100003    4   udp   2049  nfs
        100227    2   udp   2049  nfs_acl
        100227    3   udp   2049  nfs_acl
        100021    1   udp  34627  nlockmgr
        100021    3   udp  34627  nlockmgr
        100021    4   udp  34627  nlockmgr
        100021    1   tcp  46375  nlockmgr
        100021    3   tcp  46375  nlockmgr
        100021    4   tcp  46375  nlockmgr
    

    4.配置共享目录/share,允许192.168.25.*访问

    [root@localhost ~]# mkdir /share    //创建共享目录
    [root@localhost ~]# ll -d /share/      //查看目录信息
    drwxr-xr-x. 2 root root 4096 Dec 30 13:55 /share/
    [root@localhost ~]# chown -R nfsnobody:nfsnobody /share/  //更改目录所属用户和所属组
    [root@localhost ~]# ll -d /share/
    drwxr-xr-x. 2 nfsnobody nfsnobody 4096 Dec 30 13:55 /share/
    [root@localhost ~]# vi /etc/exports 
    /share 192.168.25.*(rw,sync)  # 添加此字段 wq保存   ///share 192.168.25.* 本机IP网段
    

    5.查看NFS共享目录信息

    [root@localhost ~]# showmount -e 192.168.25.231  //本机IP
    Export list for 192.168.25.231:
    /share 192.168.25.*
    

    6.NFS客户端挂载共享目录/share

    [root@localhost ~]# mount -t nfs 192.168.25.231:/share /mnt
    [root@localhost ~]# df -h
    文件系统                 容量  已用  可用 已用% 挂载点
    /dev/mapper/centos-root   17G  1.8G   16G   11% /
    devtmpfs                 476M     0  476M    0% /dev
    tmpfs                    488M     0  488M    0% /dev/shm
    tmpfs                    488M  7.9M  480M    2% /run
    tmpfs                    488M     0  488M    0% /sys/fs/cgroup
    /dev/sda1               1014M  130M  885M   13% /boot
    tmpfs                     98M     0   98M    0% /run/user/0
    192.168.25.231:/share     17G  1.8G   16G   11% /mnt
    

    7.NFS客户端排错思路

    试客户端与服务端网络是否可否,如在客户端使用ping IP地址

    在服务端自己挂载看看是否能够正常挂载

    检查服务端防火墙规则,初学者可以选择直接关闭防火墙

    8.管理NFS共享目录

    exportfs命令可以导出NFS服务器上的共享目录、显示共享目录,或者不导出共享目录。

    命令语法:

    exportfs [选项][目录]

    选项 含义
    -a 导出或不导出所有的目录
    -v 显示导出列表的同时,也显示导出选项的列表
    -u 不导出指定的目录。当和-a选项一起时,不导出所有的目录
    -f 指定一个新的导出文件,而不是/etc/exports文件
    -r 重新导出所有的目录
    -o<选项> 指定导出选项列表

    查看NFS共享目录信息

    showmount [选项][NFS服务器]

    选项 含义
    -a 同时显示客户端的主机名或IP地址以及所挂载的目录
    -e 显示NFS服务器的导出列表
    -d 只显示已经被挂载的NFS共享目录信息

    9.NFS配置文件权限参数说明

    参数名称 参数用途
    rw 共享目录具有读写权限
    ro 共享目录具有只读权限
    sync 请求或写入数据时,数据同步写入到NFS Server硬盘中。数据安全不会丢,缺点,性能比不启用该参数要差。
    async 请求或写入数据时,先返回请求,再将数据写入到内存缓存和硬盘中,即异步写入数据。此参数可以提升NFS性能,但是会降低数据的安全。因此,一般情况下建议不用,如果NFS处于瓶颈状态,并且允许数据丢失的话可以打开此参数提升NFS性能。写入时数据会先到内存缓冲区,等硬盘有空档再写入磁盘,这样可以提升写入效率!风险为若服务器宕机或不正常关机,会损失缓冲区未写入硬盘的数据(解决办法:服务器主板电池或加UPS不间断电源)!
    root_squash root用户的所有请求映射成如nfsnobody(匿名)用户一样的权限
    no_root_squash 关闭root_squash
    all_squash 映射所有的UID和GID为匿名用户
    no_all_squash 保留共享文件的UID和GID(默认)
    anonuid 指定NFS服务器/etc/passwd文件中匿名用户的UID
    anongid 指定NFS服务器/etc/passwd文件中匿名用户的GID
    secure NFS通过1024以下的安全TCP/IP端口发送
    insecure NFS通过1024以上的端口发送
    wdelay 如果多个用户要写入NFS目录,则归组写入(默认)
    no_wdelay 如果多个用户要写入NFS目录,则立即写入,当使用async时,不需要设置
    subtree_check 如果共享/usr/bin之类的子目录时,强制NFS检查父目录的权限
    no_subtree_check 和subtree_check相对,不检查父目录权限
    hide 在NFS共享目录中不共享其子目录
    nohide 共享NFS目录的子目录
    mp 如果它已经成功挂载,那么使得它只导出一个目录
    fsid NFS需要能够识别每个它导出的文件系统。通常情况下它会为文件系统使用一个UUID,或者该设备保持文件系统的设备号

    负载均衡和反向代理服务器配置

    在LB(负载均衡)服务器上面配置

    (就是第一个创建的那个服务器)

    编辑nginx.conf

    vi /application/nginx/conf/nginx.conf
    

    文件更改为

    如果要写注释, 中文乱码的话, 可以临时配为utf8编码. 在vim的命令模式下输入:set encoding=utf8, 就可以输入中文了

    建议下载下来使用vscode装nginx插件进行编辑会比较方便

    # 配置文件内容
    
    worker_processes  1;
    
    
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        keepalive_timeout  65;
    
        # 静态请求服务器池
        upstream static_pools {
            server 192.168.25.150:80 weight=1;
        }
    
        # 动态请求服务器池
        upstream dynamic_pool {
            server 192.168.25.151:8001 weight=1;
            server 192.168.25.152:8001 weight=1;
        }
    
        # 移动端服务器池
        upstream mobile_pools {
            server 192.168.25.160:80 weight=1;
        }
    
        # 后端api服务器
        server {
            listen       8080;
            server_name  api.meiduo.site;
            location / {
                include uwsgi_params;
                uwsgi_pass dynamic_pool;
            }
    
            access_log off;
    
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
    
        }
    
        # 提供前端页面访问
        server {
            listen      80;
            server_name  www.meiduo.site;
    
            # 如果访问url为:http://www.meiduo.site/xadmin就交给meiduo池
            location /xadmin{
                include uwsgi_params;
                uwsgi_pass dynamic_pool;
            }
    
            # 如果请求url为:http://www.meiduo.site/cheditor就交给meiduo池
            location /cheditor{
                include uwsgi_params;
                uwsgi_pass dynamic_pool;
            }
    
            # 请求uri以/开头就交给这个location区块进行处理,例如:/static
            location / {
                # 如果客户端设备user_agent为iphone,就交给iphone_pools池
                if ($http_user_agent ~* "iphone")
                {
                    proxy_pass http://mobile_pools;
                }
                # PC端访问就交给static_pools池处理
                proxy_pass http://static_pools;
            }
            access_log off;
        }
    }
    
    

    启动nginx服务

    /application/nginx/sbin/nginx
    

    NFS 服务器配置

    mkdir /project
    # 配置挂载目录
    cat /etc/exports
    # 配置内容
    /share 192.168.25.*(rw,sync)
    # 重启NFS服务
    systemctl restart rpcbind
    systemctl restart nfs
    

    配置完成之后把项目上传到/project目录里面

    配置uwsgi和uwsgi2服务器

    在uwsgi1和uwsig2服务器上操作:

    # 创建虚拟环境
    mkvirtualenv -p python3 meiduo
    # 切换到meiduo虚拟环境
    workon mediuo
    # 安装uwsgi包
    pip install uwsgi
    mkdir /project
    # 挂载NFS服务器/project目录到uwsgi服务器的/project
    mount -t nfs 172.16.1.14:/project /project
    # 查看当前服务器挂载情况
    df -h
    # 输出
    文件系统                 容量  已用  可用 已用% 挂载点
    /dev/mapper/centos-root   36G  2.4G   33G    7% /
    devtmpfs                 226M     0  226M    0% /dev
    tmpfs                    237M     0  237M    0% /dev/shm
    tmpfs                    237M  8.8M  228M    4% /run
    tmpfs                    237M     0  237M    0% /sys/fs/cgroup
    /dev/sda1               1014M  143M  872M   15% /boot
    tmpfs                     48M     0   48M    0% /run/user/0
    172.16.1.14:/project      17G  1.8G   16G   11% /project
    # 安装项目中用到的pip包
    cd /project/meiduo/meiduo_mall
    pip install -r requirements.txt  # 这个文件是在开发环境中通过pip freeze >requirements.txt生成的
    cd /root
    # 创建uwsgi.ini文件
    touch uwsgi.ini
    

    uwsgi1配置

    [uwsgi]
    #使用nginx连接时使用,Django程序所在服务器地址
    socket=172.16.1.11:8001
    #直接做web服务器使用,Django程序所在服务器地址
    #http=172.16.1.11:8000
    #项目目录
    chdir=/project/meiduo/meiduo_mall
    #项目中wsgi.py文件的目录,相对于项目目录
    wsgi-file=meiduo_mall/wsgi.py
    # 进程数
    processes=4
    # 线程数
    threads=2
    # uwsgi服务器的角色
    master=True
    # 存放进程编号的文件
    pidfile=uwsgi.pid
    # 日志文件,因为uwsgi可以脱离终端在后台运行,日志看不见。我们以前的runserver是依赖终端的
    daemonize=uwsgi.log
    # 指定依赖的虚拟环境
    virtualenv=/root/.virtualenvs/meiduo
    

    uwsgi2配置

    [uwsgi]
    #使用nginx连接时使用,Django程序所在服务器地址
    socket=172.16.1.12:8001
    #直接做web服务器使用,Django程序所在服务器地址
    #http=172.16.1.12:8000
    #项目目录
    chdir=/project/meiduo/meiduo_mall
    #项目中wsgi.py文件的目录,相对于项目目录
    wsgi-file=meiduo_mall/wsgi.py
    # 进程数
    processes=4
    # 线程数
    threads=2
    # uwsgi服务器的角色
    master=True
    # 存放进程编号的文件
    pidfile=uwsgi.pid
    # 日志文件,因为uwsgi可以脱离终端在后台运行,日志看不见。我们以前的runserver是依赖终端的
    daemonize=uwsgi.log
    # 指定依赖的虚拟环境
    virtualenv=/root/.virtualenvs/meiduo
    

    uwsgi启动命令

    # 启动uwsgi服务器
    uwsgi --ini uwsgi.ini
    # 停止uwsgi服务器
    uwsgi stop uwsgi.ini
    

    5. www服务器

    处理PC端静态文件请求

    cat nginx.conf
    # 配置文件
    worker_processes  1;
    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"';
        sendfile        on;
        keepalive_timeout  65;
        server {
           listen 80;
           server_name www.meiduo.site;
           location / {
              root html/front_end_pc; 
              # 相对路径,把前端文件夹放到Nginx安装路径下html目录下,我这里的路径是/application/nginx/html
              index index.html index.htm;
           }
           access_log logs/access_www.log main;
        }
    }
    

    启动nginx服务

    /application/nginx/sbin/nginx
    

    6. wap服务器

    处理移动端静态文件请求

    cd /application/nginx/html
    # 因为没有移动端前端页面,所以这里简单创建了一个测试页面
    mkdir wap
    echo "mobile_page" > wap/index.html
    

    Nginx配置

    cat nginx.conf
    worker_processes  1;
    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"';
        sendfile        on;
        keepalive_timeout  65;
        server {
           listen 80;
           server_name www.meiduo.site;
           location / {
              root html/wap;
              # 相对路径,把前端文件夹放到Nginx安装路径下html目录下,我这里的路径是/application/nginx/html
              index index.html index.htm;
           }
           access_log logs/access_www.log main;
        }
    }
    

    启动nginx服务

    /application/nginx/sbin/nginx
    

    7. MRCS服务器(资源有限,所以把这些东西安装在一台服务器上面)

    mkdir /project
    # 挂载NFS服务器/project目录到uwsgi服务器的/project
    mount -t nfs 172.16.1.14:/project /project
    # 查看当前服务器挂载情况
    df -h
    # 输出
    文件系统                 容量  已用  可用 已用% 挂载点
    /dev/mapper/centos-root   36G  2.4G   33G    7% /
    devtmpfs                 226M     0  226M    0% /dev
    tmpfs                    237M     0  237M    0% /dev/shm
    tmpfs                    237M  8.8M  228M    4% /run
    tmpfs                    237M     0  237M    0% /sys/fs/cgroup
    /dev/sda1               1014M  143M  872M   15% /boot
    tmpfs                     48M     0   48M    0% /run/user/0
    172.16.1.14:/project      17G  1.8G   16G   11% /project
    # 创建虚拟环境
    mkvirtualenv -p python3 meiduo
    # 切换到meiduo虚拟环境
    workon mediuo
    # 安装项目中用到的pip包
    cd /project/meiduo/meiduo_mall
    pip install -r requirements.txt  # 这个文件是在开发环境中通过pip freeze >requirements.txt生成的
    

    配置supervisor

    mkvirtualenv -p python2 supervisor
    # 这里创建python2的虚拟环境,因为supervisor不支持python3
    workon supervisor
    pip install supervisor
    # 生成supervisor配置文件
    echo_supervisord_conf > /etc/supervisord.conf
    # 创建日志目录
    mkdir /var/log/celery
    

    创建celery.ini文件

    cat /etc/celery.ini
    # 配置内容
    [program:celery]
    # celery命令的绝对路径
    command=/root/.virtualenvs/meiduo/bin/celery -A celery_tasks.main worker -l info
    # 项目路径
    directory=/project/meiduo/meiduo_mall
    # 日志文件路径
    stdout_logfile=/var/log/celery/celery.log
    # 自动重启
    autorestart=true
    # 如果设置为true,进程则会把标准错误输出到supervisord后台的标准输出文件描述符
    redirect_stderr=true
    

    修改/etc/supervisord.conf文件

    [include]
    files = celery.ini
    

    supervisor命令

    # 以守护进程的形式运行一组应用程序。
    supervisord
    # 更新新的配置到supervisord   
    supervisorctl update
    # 查看正在守护的进程
    supervisorctl
    

    8. 访问测试

    在hosts文件里面添加本地解析
    windows系统hosts文件路径:系统盘windowssystem32driversetc
    Linux系统和MAC系统hosts文件路径:/etc/hosts

    172.16.1.10 www.meiduo.site api.meiduo.site
    

    PC端访问效果

  • 相关阅读:
    【LeetCode-栈】栈排序
    【LeetCode-数组】旋转数组
    【LeetCode-数组】两个数组的交集 II
    【LeetCode-树】二叉树的层次遍历 II
    【LeetCode-字符串】Fizz Buzz
    【LeetCode-数组】数组的相对排序
    解决Oracle表中数据乱码的问题
    docker搭建mysql 用户名密码忘记了怎么办
    java中如何将string 转化成long
    http三次握手四次挥手
  • 原文地址:https://www.cnblogs.com/gaidy/p/9784921.html
Copyright © 2020-2023  润新知