搭建服务器

本地开发完Web App后,只在本地能跑起来是远远未能符合工程应用的需要,我们还需要在服务器上进行账号设置、环境搭建、安装和启动必要的服务、部署自动化、服务进程管理、Web服务设置等的工作,这样才能使我们服务器上的Web在被正常访问的基础上,更高效、稳定地部署和发布。

基本概念

wsgi

  • wsgi: (the Python Web Server GateWay Interface) 是一种通信协议
    • python web 框架编写的应用程序 <==> 后端服务器之间的通信规范.
    • PEP 3333 中描述了 web server 如何与 web application 通信的规范
    • 要实现 wsgi 协议,必须同时实现web server 和 web application
    • 当前运行在 wsgi 协议之上的web框架有 Bottle, Flask, Django
  • uwsgi: 是一种线路协议
    • 与wsgi是两种东西,是uWSGI服务器的独占协议
  • uWSGI: 是一个web服务器的名字
    • uWSGI旨在为部署分布式集群的网络应用开发一套完整的解决方案
    • 主要面向web及其标准服务。由于其可扩展性,能够被无限制的扩展用来支持更多平台和多语言
    • 实现了WSGI协议、uwsgi协议等
    • uWSGI服务器自己实现了基于uwsgi协议的server部分,我们只需要在uwsgi的配置文件中指定application的地址,uWSGI就能直接和应用框架中的WSGI application通信。
    • uWSGI的主要特点是:
      • 超快的性能
      • 低内存占用
      • 多app管理
      • 详尽的日志功能(可以用来分析app的性能和瓶颈)
      • 高度可定制(内存大小限制,服务一定次数后重启等)

Tomcat

运行在JVM之上,绑定IP地址并监听TCP端口的Web服务器。

同时负责:

  • 管理Servlet程序的生命周期
  • 将URL映射到指定的Servlet进行处理
  • 与Servlet程序合作处理HTTP请求——根据HTTP请求生成HttpServletResponse对象并传递给Servlet进行处理,将Servlet中的HttpServletResponse对象生成的内容返回给浏览器

Nginx

轻量级的Web服务器/反向代理服务器/电子邮件(IMAP/POP3)代理服务器/负载均衡服务器

适合偏静态、高并发的场景

可与uWSGI、Tomcat搭配使用

Apache

世界使用排名第一的Web服务器,具有重量级、耗资源、低性能的特点,也具备兼容性强、稳定性高、模块丰富。

一般用于处理数据量大,又需要快速响应的场景

对比Nginx,Apache是同步多进程模型,一个连接对应一个进程,Nginx是异步的,多个连接(万级别)可以对应一个进程

Django内置服务器 + Nginx 部署

Django 内置的服务器软件,可以认为是简化版的 Apache

下面使用阿里云ECS服务器演示(略过购买ECS、购买弹性公网IP、ECS绑定IP的过程)。

修改密码

无论是Linux还是Ubuntu,第一次登录时可能会出现提示Login Incorrect,解决办法是

  1. 云服务器ECS->实例->选择操作的实例;
  2. 点击“远程连接”旁边的更多;
  3. 重置一次密码(可能需要手机短信验证),注意这里的密码修改的不是6位数字那个远程连接的密码,而是root账户的密码;
  4. 密码修改成功后,必须手动重启一次实例;
  5. 等待重启成功后,再次连接到远程,输入 root 和 刚刚修改过的密码(密码不明文显示),就可以正常登录了。
    config_server_pwd

远程连接

有两种方式连接,一是通过阿里云上提供的网页版命令行连接,而是本地命令行上ssh连接。

网页版连接时需要注意与本地的输入方式差异,一般通过下图右上角的”复制命令输入“完成,因为页面使用部分字母作为快捷方式,故无法直接输入这些字母。
config_server_ssh

本地命令方式下,可以使用客户端ssh的id公钥代替输入密码来登录远程主机,步骤如下

$ ssh-keygen -t  rsa //创建公钥及秘钥对,默认路径为~/.ssh/id_rsa
$ ssh-copy-id -i ~/.ssh/id_rsa.pub  root@xx.xx.xx.xx //把公钥复制到远程主机
& ssh root@xx.xx.xx.xx -p port//登录

软件更新

apt-get的应用

apt-get主要用于自动从互联网的软件仓库中搜索、安装、升级、卸载软件或操作系统。

sudo apt-get update //更新本机中的软件包的数据库缓存
sudo apt-cache search <name> //查找包含部分关键字的软件包
sudo apt-get install <package_name> //安装指定的软件(自动安装依赖),-d 只下载包,不解压安装
apt-get install package=version //安装指定版本
apt-get source <source_code_name> //下载软件包源代码
apt-get remove packagename //卸载软件,同时会卸载依赖,但保留配置,--purge 删除配置
apt-get clean //清理所有的缓存文件
dpkg  -l //查找安装在机器上面的软件包

参考链接

python3的安装

sudo apt-get install python3 //安装python3.6,可指定3.7,系统默认有python2
python3 -V //查看python3的版本号
sudo apt-get install pip3 //安装对应3.6的版本,3.7可使用sudo python3.7 get-pip.py

虚拟py环境搭建

pip3 install virtualenv
mkdir awesome-python3-webapp
virtualenv venv -p python3
source venv/bin/activate

(venv)# pip install aiohttp
(venv)# pip install jinja2
cd awesome-python3-webapp
...
git init
git add .
git commit -m "Initial commit"
git remote add origin <remote_url>
git push -u origin master

同步文件

从本地同步到远程

rsync -avz -e ssh /Path/to/uploadFile root@xx.xx.xx.xx:/Path/to/file //使用默认端口
rsync -avz -e 'ssh -p 61124' /Path/to/uploadFile/ root@xx.xx.xx.xx:/Path/to/file //指定端口

从远程同步到本地

rsync -avzP -e ssh root@xx.xx.xx.xx:/Path/to/downloadFile /Path/to/file
rsync -avzP -e 'ssh -p 61124' root@xx.xx.xx.xx:/Path/to/downloadFile /Path/to/file

开放端口

查看端口
使用 lsof 命令来查看某一端口是否开放,例:

lsof -i:80

如果有显示说明已经开放了,如果没有显示说明没有开放

是否在监听端口,例:

netstat -aptn
netstat -nupl (UDP类型的端口)
netstat -ntpl (TCP类型的端口)

开放端口
“实例”->”更多”->”网络和安全组”->”安全组配置”->”(安全组列表)配置规则”->”添加安全组规则”

一般只需设置入规则方向、TCP协议、端口范围、默认权对象(0.0.0.0/0)

检测
在远程主机上使用以下指令检测是否能访问

curl <ip>:<port> //或者使用 wget <ip>:<port>

若出现Connection refused的错误

netstat -tnl

配置数据库

mysql:

官网下载

下载完注意保存默认提供的密码。

修改密码
mysqladmin -u root password [password]

设置环境变量

$ cd ~
$ vim ./.bash_profile
> export PATH=$PATH:/usr/local/mysql/bin
$ source ~/.bash_profile 
$ echo $PATH

在系统设置->MySQL->打开服务

登入

$ mysql -u root -p
$ mysql -uxxx -hx.x.x.x -pxxx -P8066 # 远程登录

重置密码

> SET PASSWORD FOR ['username']@['host']=PASSWORD('[newPassword]');

创建账号

> CREATE USER '[username]'@'[host]' IDENTIFIED BY '[password]';

删除账号

> DROP USER '[username]'@'[host]';

授权

> GRANT [ALL] ON [databasename].[tablename] TO '[username]'@'[host]'

取消授权

> REVOKE [ALL] ON [databasename].[tablename] FROM '[username]'@'[host]'

查询及创建库/表

#显示数据库列表:
>show databases; 
#选择使用某个数据库:
>use [databaseName];
#创建数据库:
>create database [databaseName];
#显示库中的数据表:
>show tables; 
#显示数据表的结构: 
>describe [tableName]; 
#建表: 
create table 表名 (字段设定列表); 
#删库和删表: 
drop database 库名; 
drop table 表名; 
#将表中记录清空:
delete from 表名; 
#显示表中的记录: 
select * from 表名;

卸载

$ sudo rm /usr/local/mysql
$ sudo rm -rf /usr/local/var/mysql
$ sudo rm -rf /usr/local/mysql*
$ sudo rm ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
$ sudo rm -rf /Library/StartupItems/MySQLCOM
$ sudo rm -rf /Library/PreferencePanes/My*

$ subl /etc/hostconfig` 
# Remove the line MYSQLCOM=-YES-

$ rm -rf ~/Library/PreferencePanes/My*
$ sudo rm -rf /Library/Receipts/mysql*
$ sudo rm -rf /Library/Receipts/MySQL*
$ sudo rm -rf /private/var/db/receipts/*mysql*

linux下开启、关闭、重启mysql服务命令

若启动应用时,报链接不到mysql的错误(Can’t connect to MySQL server on ‘x.x.x.x’),可检查以下几点:

  1. 输入”service mysqld status”查看mysql服务是否已启动;
  2. 查账号是否存在,且是否已授权给对应表 use mysql; select host,user from user;
  3. 账号密码是否正确 mysql -u username -p passwd
  4. 允许任何主机登陆MySQL,设置/etc/mysql/mysql.conf.d/mysqld.cnf bind-address=0.0.0.0 和 port=3360;
  5. 关闭防火墙 systemctl stop firewalld systemctl status firewalld
  6. 云服务器的安全组开放对应端口3360.

控制mysql服务的操作:

1)启动

  • 使用 service 启动:service mysql start
  • 使用 mysqld 脚本启动:/etc/inint.d/mysql start
  • 使用 safe_mysqld 启动:safe_mysql&
    2)停止
  • 使用 service 启动:service mysql stop
  • 使用 mysqld 脚本启动:/etc/inint.d/mysql stop
  • mysqladmin shutdown
    3)重启
  • 使用 service 启动:service mysql restart
  • 使用 mysqld 脚本启动:/etc/inint.d/mysql restart

四、查看mysql状态

mysql

用户管理

创建用户

sudo adduser xx
  • xx为用户名
  • 会自动创建用户主目录
  • 会自动指定系统Shell版本 /bin/bash
  • 需用户指定密码
  • 自动调用 /etc/adduser.conf
  • 自定义参数
    • –home 指定主目录
    • –quiet 只打印警告和错误信息,忽略其它信息
    • –conf 指定configuration文件
    • –force-badname 用户名合法性弱检查

方法2

sudo useradd xx
sudo useradd -d /home/xx -m xx
  • 什么都不指定
  • 自定义参数
    • -d 指定主目录
    • -m 如果存在不再创建,但是此目录并不属于新创建用户;如果主目录不存在,则强制创建; -m和-d一块使用
    • -s 指定用户登录时的shell版本
    • -M 不创建主目录

修改密码

sudo passwd xx

删除用户

sudo userdel xx
# 连同主目录一并删除
sudo userdel -r xx
  • /etc/passwd 使用者账号资讯,可以查看用户信息
  • /etc/shadow 使用者账号资讯加密
  • /etc/group 群组资讯
  • /etc/default/useradd 定义资讯
  • /etc/login.defs 系统广义设定
  • /etc/skel 定义档的目录

授权用户

chown -R xx:xx /home/xx
chmod 760 /home/xx

在不同用户间切换执行命令或脚本

$ su - test_user <<EOF
$ echo ~/
$ ls -al
$ EOF
# EOF 可以是其它标识符,表示后续的输入作为子命令或子Shell的输入,直到遇到EOF为止,再返回到主Shell,例如还可以用到 mysql 的SQL语句去,作为跟在mysql账号密码后的语句输入。

进程管理

Supervisor是用Python开发的监控服务进程工具,可以监听、启动、停止、重启一个或多个进程。当一个进程意外被杀死,利用Supervisor监听到进程死后,会自动将它重启,自动恢复,不再需要自己写shell脚本来控制。

1.安装Supervisor:

yum install supervisor
easy_install supervisor
supervisord -v

2.修改配置:安装好后,/etc/supervisor会生成一个supervisord.conf文件及一个conf.d文件目录。supervisord.conf是默认的配置;conf.d中是放指定进程的自定义配置。

conf文件中,使用[xx]分隔开配置中的模块,其中[include]是导入其它自定义的进程配置文件,默认配置是制定.ini的格式,亦可是*.conf。

添加自定义配置,新建一个对应应用名为xx的xx.conf到 /etc/supervisor/conf.d/xx.conf,写入如下内容

[program:xx]

command     = /srv/xx/www/app.py
directory   = /srv/xx/www
user        = userName
startsecs   = 3

redirect_stderr         = true
stdout_logfile_maxbytes = 50MB
stdout_logfile_backups  = 10
stdout_logfile          = /srv/xx/log/app.log

因为supervisor不能监控后台进程,所以配置中的command 不能为后台运行命令。如果.py文件中不指定执行环境,例如#!/usr/bin/env python3#!/srv/xx/venv/bin python3,那command就需要设置完整的指令 /path/python3 /path/xx.py

执行start之前先指定配置的路径(直接使用supervisorctl可能会报错 unix:///var/run/supervisor/supervisor.sock no such file。执行-c 后也免去了start)

sudo supervisord -c /etc/supervisord.conf  
sudo supervisorctl -c /etc/supervisord.conf  

supervisord 是启动 supervisor 守护进程(类似于 systemd 或 init.d 这种用于托管进程的服务)。supervisorctl 是 supervisord 的命令行控制台,它的其它操作指令还包括

supervisorctl status #查看所有进程的状态
supervisorctl stop es #停止es
supervisorctl start es #启动es
supervisorctl restart es #重启es
supervisorctl update #配置文件修改后可以使用该命令加载新的配置
supervisorctl reload #重新启动配置中的所有程序
... #es可换成all,管理配置中的所有进程

最后开始监听某进程(当然需要在xx进程已开启的状态下进行)

$ sudo supervisorctl reload
$ sudo supervisorctl start xx
$ sudo supervisorctl status
xx                RUNNING    pid 1401, uptime 5:01:34

3.遇到的问题

1) 如果执行 start 指令时提示spawn error,可以查询日志

tail -20 /var/log/supervisor/supervisord.log

Exit code 127 一般意味着找不到指令,对command中的指令添加绝对路径。也可能是配置没重加载成功,可尝试重启supervisord进程(可参考下一点问题解决办法)

2) 如果执行 supervisord -c 时,提示以下错误:
Error: Another program is already listening on a port that one of our HTTP servers is configured to use. Shut this program down first before starting supervisord.

一般是进程已经打开过,杀掉进程重试即可

ps -ef | grep supervisord
kill -s SIGTERM pid

3) 如果执行 start 指令时提示 file is not executable,则可能是权限问题,修改启动文件的权限 chmod chmod a+x app.py 即可。

配置Nginx

把配置文件xx放到/etc/nginx/sites-available/目录下(一般是在copy default文件的基础上修改。如果和default监听一样的端口等设置,则需要将default删除,保持一个应用一个配置,其中监听的端口等设置必须各不一样)

server {
        listen  80; #监听80端口
        root    /srv/xx/www;
        access_log      /srv/xx/log/access_log;
        error_log       /srv/xx/log/error_log;

        # server_name x.xx.com; # 配置域名

        # 处理静态文件 /favicon.ico;
        location /favicon.ico {
                root /srv/xx/www
        }

        # 处理静态资源
        location ~ ^\/static\/.*$ {
                root /srv/xx/www
        }

        # 动态请求转发到9000端口
        location / {
                proxy_pass      http://127.0.0.1:9000;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        Host    $host;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for
        }
}

然后在/etc/nginx/sites-enabled/目录下创建软链接

sudo ln -s /etc/nginx/sites-available/xx

让Nginx重新加载配置文件,webapp应该就能正常运行

sudo /etc/init.d/nginx reload
sudo service nginx restart # 或通过service重启

nginx既可做正向代理,也可做反向代理(反向代理简单来说,就是像客户端访问80端口,帮你定位到9000端口,这样的转发功能),以上例子中相关的参数如下

  • X-Forwarded-For,是用于记录代理信息的,每经过一级代理(匿名代理除外),代理服务器都会把这次请求的来源IP追加在X-Forwarded-For中
  • X-Real-IP,只记录真实发出请求的客户端IP

如不想服务器会响应超时,可设

server {
    ...
    client_body_timeout 1w;
}
http {
    fastcgi_read_timeout 1w;
    fastcgi_send_timeout 1w;
    proxy_read_timeout 1w;
    proxy_send_timeout 1w;
    uwsgi_send_timeout 1w;
    uwsgi_read_timeout 1w;
}

其中的参数参考时间单位:

ms    milliseconds
s    seconds
m    minutes
h    hours
d    days
w    weeks
M    months, 30 days
y    years, 365 days

安装Redis

MacOS

$ wget http://download.redis.io/releases/redis-5.0.0.tar.gz
$ tar xzf redis-5.0.0.tar.gz
$ cd redis-5.0.0
$ make

若make过程提示


“_redisAsyncSetDisconnectCallback”, referenced from: _sentinelReconnectInstance in sentinel.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: * [redis-server] Error 1
make: *
[all] Error 2
symbol(s) not found for architecture x86_64

可通过卸载brew中的binutils解决

$ brew uninstall binutils
$ make distclean
$ make

然后继续

$ cd src
$ ./redis-server [../redis.conf]
$ ./redis-cli
redis> set foo bar
OK
redis> get foo

Ubuntu

$sudo apt-get update
$sudo apt-get install redis-server
$ redis-server
$ redis-cli
redis 127.0.0.1:6379> ping
PONG

Django + uWSGI + Nginx

NodeJS + Nginx

node app.js

Apache

查看版本

$ httpd -v
Server version: Apache/2.4.34 (Unix)
Server built:   Feb 22 2019 20:20:11

启动 Apache

$ sudo apachectl start

访问服务器

浏览器上访问 http://127.0.0.1http://localhost
站点的根目录为系统级根目录 /Library/WebServer/Documents

停止 Apache

$ sudo apachectl stop

重启 Apache

$ sudo apachectl restart

创建用户级根目录

  • 用户目录下创建 Sites,及touch Sites/.localized
  • 检查 username.conf 文件(username为当前用户名),是否存在与/etc/apache2/users,没有则创建,权限设为sudo chmod 644 username.conf
  • 配置username.conf(注意替换username)
<Directory "/Users/username/Sites/">
    Options Indexes MultiViews FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
    Require all granted
</Directory>
  • 编辑 /etc/apache2/httpd.conf 文件,解除以下注释
LoadModule authz_core_module libexec/apache2/mod_authz_core.so
LoadModule authz_host_module libexec/apache2/mod_authz_host.so
LoadModule userdir_module libexec/apache2/mod_userdir.so
LoadModule include_module libexec/apache2/mod_include.so
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
Include /private/etc/apache2/extra/httpd-userdir.conf
  • 编辑 /etc/apache2/extra/httpd-userdir.conf 文件,解除以下注释
Include /private/etc/apache2/users/*.conf

参考

wsgi、uwsgi、uWSGI、nginx、apache
使用 supervisor 管理进程
Nginx 配置详解
部署Web App
shell脚本中使用其他用户执行脚本
Get Apache, MySQL, PHP and phpMyAdmin working on macOS Sierra


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 mingfungliu@gmail.com

文章标题:搭建服务器

文章字数:4.3k

本文作者:Mingfung

发布时间:2019-04-06, 00:00:00

最后更新:2022-01-13, 17:29:04

原始链接:http://blog.ifungfay.com/后端/搭建服务器/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏

宝贝回家