美文网首页spring我爱编程
搭建全功能服务器(Nginx+Tomcat+PHP+SSL)

搭建全功能服务器(Nginx+Tomcat+PHP+SSL)

作者: daling菜鸟 | 来源:发表于2017-12-06 09:45 被阅读151次

    本文将介绍Linux环境下如何安装Web服务基础运行环境,包括以下内容:

    安装jdk

    安装Tomcat

    安装MySQL

    安装PHP

    安装Nginx

    安装SSL证书

    整合Nginx和Tomcat

    整合完成后,服务器将可以满足大部分应用场景需求。

    以下案例使用的服务器是一款美国的VPS,腾讯云、阿里云等云主机搭建过程与之类似。

    首先看一下服务器的参数

    这台服务器内存有1G,使用的是CentOS7 64位系统,可以跑中小型的Java Web程序。特别提醒,由于目前的项目一般都会用到springmvc、mybatis等一堆框架,对内存的消耗很大,建议内存最低配置要1G以上。以这台服务器为例,只跑一个应用,由于用了较多的框架,tomcat内存占用已达到277M。

    tomcat占用

    之前我图省钱选择了768M内存的VPS,发现每隔一段时间Tomcat就无缘无故shutdown,花了很长时间排查原因,最后查看系统日志才发现是由于java内存占用过高而被系统 强制kill掉。

    事前准备

    由于这台VPS默认的语言环境是英文,所以需要先切换到中文。

    (1)设置语言

    export LANG="zh_CN.UTF-8"

    (2)重新载入

    . /etc/profile

    (3)检查修改结果

    echo $LANG

    此外,由于是美国的服务器,所以还要将系统的时间改为北京时间,执行以下命令:

    (1)修改日期

    date -s 16/11/2017

    (2)修改时间(这里是上午11:35)

    date -s 111:35

    (3)将时钟写入CMOS,确保重启后依然生效(记得不要漏了这一句)

    clock -w

    (4)修改时区

    cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

    会提示是否覆盖,选Y

    安装JDK

    先检查一下系统是否已经装了jdk

    rpm -qa | grep jdk

    某些系统可能安装了openjdk,不过据说这个版本可能兼容性不是很好,你可以看情况选择是否要卸载而重新安装Oracle版本。我这里选择的是卸载后重新安装。

    (1)卸载

    yum remove java-1.7.0-openjdk

    (2)安装Oracle官方的JDK

    先要下载rpm安装包,可以在浏览器打开jdk下载页面,右键获取链接。但是目前网页需要进行用户验证(需要你点击accept才能下载),所以wget的时候要加上一些参数来跳过这个检查

    wget --no-check-certificate --no-cookie --header "Cookie:oraclelicense=accept-secureback-cookie;" http://download.oracle.com/otn-pub/java/jdk/8u121-b13/e9e7ea248e2c4826b92b3f075a80e441/jdk-8u121-linux-x64.rpm

    (3)直接安装

    rpm -ivh jdk-8u121-linux-x64.rpm

    系统默认会将jdk安装到这个位置:/usr/java/jdk1.8.0_121

    安装Tomcat

    Tomcat可以使用yum或者下载安装的方式,我这里采用的是下载安装的方式。

    (1)下载压缩包

    wget http://www-us.apache.org/dist/tomcat/tomcat-8/v8.5.11/bin/apache-tomcat-8.5.11.tar.gz

    (2)解压缩

    tar -zxvf apache-tomcat-8.5.11.tar.gz

    (3)将apache-tomcat-8.5.11 移动到/usr/local目录下

    mv apache-tomcat-8.5.11 /usr/local

    (4)将apache-tomcat-8.5.11目录名更名为tomcat

    mv/usr/localapache-tomcat-8.5.11/usr/localtomcat

    为了安全起见,我们一般会将诸如Tomcat、Nginx等对外提供服务应用的目录权限修改一下。

    (1)新建一个tomcat用户组

    groupadd tomcat

    (2)新建一个tomcat用户并加入tomcat用户组,同时限制该账户无法使用bash

    useradd -g tomcat -s /sbin/nologin tomcat

    (3)可以使用以下命令查看一下设置结果

    id tomcat

    (4)将tomcat目录的拥有者改为tomcat,并将目录权限改为770:

    chown -R tomcat:tomcat /usr/local/tomcat

    chmod -R 770 /usr/local/tomcat

    此外,我们一般还会设置Tomcat随系统自动启动。

    (1)在tomca/bin 目录下面,增加 setenv.sh 配置,catalina.sh会在tomcat启动的时候被调用。

    这个文件包含如下两行内容(Java内存参数根据自己服务器配置来修改):

    #指定tomcat pid的路径,系统将以此来区分进程

    CATALINA_PID="$CATALINA_BASE/tomcat.pid"

    #增加一些java内存配置参数,并修改一下时区,否则tomcat日志的时间可能不准确

    JAVA_OPTS="-Xms256m -Xmx512m -Xss1024K -XX:PermSize=64m -XX:MaxPermSize=128m -Duser.timezone=Asia/Shanghai"

    (2)添加服务

    切换至/usr/lib/systemd/system/目录,建立tomcat.service文件并输入以下内容:

    [Unit]

    Description=Tomcat

    After=syslog.target network.target remote-fs.target nss-lookup.target

    [Service]

    Type=forking

    PIDFile=/usr/local/tomcat/tomcat.pid

    ExecStart=/usr/local/tomcat/bin/startup.sh

    ExecReload=/bin/kill -s HUP $MAINPID

    ExecStop=/bin/kill -s QUIT $MAINPID

    PrivateTmp=true

    User=tomcat

    Group=tomcat

    [Install]

    WantedBy=multi-user.target

    (3)设置为开机启动

    systemctl enable tomcat

    (4)启动、停止、重启tomcat命令:

    #启动tomcat

    systemctl start tomcat

    #停止tomcat

    systemctl stop tomcat

    #重启tomcat

    systemctl restart tomcat

    #查看tomcat服务状态

    systemctl status tomcat.service

    systemctl status tomcat.service

    如果看到状态为active(running),表明tomcat已经成功启动。不过,这时候你还不能通过http://IP地址:8080来访问tomcat,因为我们还没有开放8080端口。先别急,我们继续往下走。

    安装PHP

    (1)先检查系统是否已经安装了php及其版本

    yum list installed | grep php

    (2)如果有安装的PHP包,先删除他们

    yum remove php.*

    (3)配置yum源(可能要试几次才能成功)

    rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm

    rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm

    (4)接着就一次性安装php及相关组件

    yum install php56w.x86_64 php56w-cli.x86_64 php56w-common.x86_64 php56w-gd.x86_64 php56w-ldap.x86_64 php56w-mbstring.x86_64 php56w-mcrypt.x86_64 php56w-mysql.x86_64 php56w-pdo.x86_64 php56w-fpm.x86_64

    (5)检查一下php是否安装成功:

    由于我们使用的是yum的安装方式,所以已经帮我们配置好相关的service了,直接启动就可以,相关命令:

    #启动

    systemctl start php-fpm

    #重启

    systemctl restart php-fpm

    #停止

    systemctl stop php-fpm

    #设置开机启动php-fpm

    systemctl enable php-fpm.service

    接下来,我们要对php进行一下配置。

    (1)打开php.ini配置文件

    vi /etc/php.ini

    (2)限制PHP只能操作指定目录下的文件,注意后面要加斜杠。

    由于我们会用到Nginx服务器,所以这里我们将PHP目录直接放到Nginx默认的web路径之下(见下文)

    open_basedir = /usr/local/nginx/html/

    另外还会有很多安全选项可以配置,如allow_url_include、allow_url_fopen、allow_url_include、display_errors等,这些选项在正式环境下建议关闭。不过由于本案例会用到phpMyAdmin这个可视化工具来管理MySQL数据库,所以暂时先保留默认状态。

    安装MySQL

    这台服务器默认安装了MariaDB(MySQL的一个分支),其用法基本跟MySQL一致,但也有微小区别(如字段大小写问题),由于我在本地开发的时候用的是MySQL,所以这里我还是换回了MySQL。

    (1)卸载MariaDB

    检查系统是否安装了mariadb

    rpm -qa | grep mariadb

    强制卸载

    rpm -e –nodeps mariadb-libs-5.5.37-1.el7_0.x86_64

    (2)下载mysql的repo源

    wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm

    (3)安装mysql-community-release-el7-5.noarch.rpm包

    rpm -ivh mysql-community-release-el7-5.noarch.rpm

    安装这个包后,会获得两个mysql的yum repo源:

    /etc/yum.repos.d/mysql-community.repo

    /etc/yum.repos.d/mysql-community-source.repo

    (4)之后就可以使用yum方式安装mysql

    yum install mysql-server

    (5)设为开机启动并立即启动服务

    systemctl enable mysqld

    systemctl start mysqld

    安装完之后要第一时间进行安全初始化设置,直接输入mysql_secure_installation

    mysql_secure_installation

    该指令会引导你完成初始化操作:

    Set root password? [Y/n] <– 回车

    New password: <– 输入ROOT密码 // KD020lzb@

    Re-enter new password: <– 再输入一次ROOT密码

    Remove anonymous users? [Y/n] <– 回车

    Disallow root login remotely? [Y/n] <– 回车

    Remove test database and access to it? [Y/n] <– 回车

    Reload privilege tables now? [Y/n] <– 回车

    (6)可以验证一下刚才设置的密码

    此外,由于我们数据库会用到中文字符集,所以要进行一下相应配置。

    (1)修改/etc/my.cnf

    vi /etc/my.cnf

    在[client]段增加:

    default-character-set=utf8

    在[mysqld]段增加:

    character-set-server=utf8

    collation-server=utf8_general_ci

    (2)配置完成后要重启服务

    systemctl restart mysqld

    安装Nginx

    我使用的是手工安装的方式,你也可以选择yum方式

    (1)Nginx的运行需要依赖以下组件,需要先安装

    yum install -y gcc-c++

    yum install -y pcre pcre-devel

    yum install -y zlib zlib-devel

    yum install -y openssl openssl-devel

    (2)下载安装包

    wget -c https://nginx.org/download/nginx-1.10.2.tar.gz

    (3)解压

    tar -zxvf nginx-1.10.2.tar.gz

    (4)进入nginx-1.10.2目录,直接编译安装

    ./configure

    make

    make install

    默认会安装到/usr/local/nginx目录。

    (5)设置开机启动,方式跟tomcat类似

    vi /usr/lib/systemd/system/nginx.service

    输入以下内容:

    [Unit]

    Description=nginx - high performance web server

    After=network.target remote-fs.target nss-lookup.target

    [Service]

    Type=forking

    PIDFile=/usr/local/nginx/logs/nginx.pid

    ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf

    ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

    ExecReload=/bin/kill -s HUP $MAINPID

    ExecStop=/bin/kill -s QUIT $MAINPID

    PrivateTmp=true

    [Install]

    WantedBy=multi-user.target

    设置开机启动并立即启动服务

    systemctl enable nginx.service

    systemctl start nginx.service

    (6)开放相关端口

    在访问应用之前,我们要先在防火墙中开放相关的端口,可以直接使用以下命令:

    firewall-cmd --permanent --zone=public --add-service=http

    firewall-cmd --permanent --zone=public --add-service=https

    firewall-cmd --reload

    这时候输入http://IP地址,应该就能够看到Nginx中默认的页面了。不过由于我们没有开放8080端口,所以你不能使用8080端口来访问Tomcat。为什么不开放8080端口呢?因为我们不需要开放,我们走的是Nginx反向代理,Nginx会自动根据配置(见下文)将内容转交给Tomcat处理。

    接下来申请SSL证书并对Nginx和Tomcat进行整合。

    申请免费的SSL证书

    目前SSL证书大部分都是要收费的。对于企业网站,建议还是花点钱买个安心吧,而对于个人网站,可以选择免费的Let's encrypt。

    安装SSL证书的过程并不复杂,第一步是申请证书,第二步是在Nginx中配置证书路径。

    (1)安装certbot工具

    yum install epel-release

    yum install certbot

    这个工具会在 你的网站根目录(也就是/usr/local/nginx/html)/.well-known 生成特殊的文件,在申请证书时,Let's Encrypt 服务会通过 http 来访问此文件,以签证服务器,所以在使用 certbot 获取证书之前,你要确保可以浏览器中能够通过http正常访问服务器。

    (2)申请证书

    certbot certonly -a webroot --webroot-path=/usr/local/nginx/html -d xxx.com -d www.xxx.com

    这里的--webroot-path指定网站的根目录,使用-d来指定应用证书的域名,如果有多个,使用多个-d就可以(一般至少应该两个,一个没有www、一个有www)。

    最终会在 /etc/letsencrypt/live/xxx.com 下,生成四个 PEM 文件

    cert.pem: 域名证书

    chain.pem:Let's Enctrypt chain certificate

    fullchain.pem:cert.pem 和 chain.pem 组成

    privkey.pem:证书的私钥

    我们需要用到的是后面的两个:fullchain.pem和privkey.pem

    (3)在Nginx中应用证书

    这一步见下一部分的具体配置。

    (4)配置自动更新证书

    因为 Let's Encrypt 的证书有效期是90天,到期前要更新证书。certbot 提供了更新证书的命令 cerbot renew。添加一个 conb job 来实现自动更新

    crontab -e

    输入

    30 2 * * 1 /usr/bin/certbot renew >> /var/log/le-renew.log

    35 2 * * 1 /usr/bin/systemctl reload nginx

    保存即可创建 cron job。以后每周1的凌晨2点30自动更新证书,2点35自动重启nginx。

    Nginx与Tomcat终极整合

    Nginx对于静态内容的处理能力非常强,跟Tomcat整合我们一般会将静态资源交给Nginx来处理,同时,考虑到我们会使用静态化技术来将页面转为html并会用到文件上传功能,所以,我们要将Nginx目录的权限也交给tomcat用户,以便其可以正常将文件写入到/usr/local/nginx/html目录下。

    chown -R tomcat:tomcat /usr/local/nginx

    修改/usr/local/nginx/conf/nginx.conf,内容如下,我已经在要关注的地方进行了说明。这个配置主要实现了以下几项功能:

    (1)与Tomcat服务器整合(支持集群)

    (2)支持ssl,对特定目录强制使用https协议,其他目录则可以分别使用两种协议

    (3)与php整合,对phpMyAdmin增加多一重auth basic验证

    #注意改为tomcat

    user tomcat;

    #根据服务器CPU数量来设

    worker_processes 1;

    error_log logs/error.log;

    #这个pid路径要跟/usr/lib/systemd/system/nginx.service中的保持一致

    pid logs/nginx.pid;

    events {

    use epoll;

    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;

    tcp_nopush on;

    keepalive_timeout 65;

    types_hash_max_size 2048;

    #注意这里我们包含了一个proxy.conf文件,该文件也是位于/usr/local/nginx/conf目录,下文会讲

    include proxy.conf;

    #下面这堆配置主要用来限制并发连接数,以及压缩内容节省带宽

    limit_conn_zone $binary_remote_addr zone=addr:10m;

    gzip on;

    gzip_min_length 1000;

    gzip_comp_level 4;

    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    open_file_cache max=655350 inactive=20s;

    open_file_cache_valid 30s;

    open_file_cache_min_uses 2;

    #定义Tomcat服务器的位置,包括端口、权重。如果要配置集群,可以在其中增加多个server,只要将localhost改为具体IP地址并设置权重即可。这里实用的是ip_hash方案,即对于集群环境下,根据ip地址来确定内容转交给哪个Tomcat处理。

    upstream tomcats{

    ip_hash;

    server localhost:8080 weight=1;

    }

    #下面定义的是默认监听端口80,我们要求所有java action(jsp)以及php都走https协议,因此80端口下放的都是静态资源(html、图片、js等),因此无须太多的配置。

    server{

    listen 80;

    server_name xxx.com www.xxx.com;

    #admin目录和phpMyAdmin目录强制使用https协议

    location ~ /(admin|phpMyAdmin)/ {

    return 301 https://$server_name$request_uri;

    }

    #do、jsp等交由Tomcat来处理

    location ~ .*.(do|jsp|action|jspx|shtml)?$ {

    proxy_pass http://tomcats;

    }

    }

    #下面是监听https协议(默认443端口)

    server {

    listen 443 ssl;

    server_name xxx.com www.xxx.com;

    server_tokens off;

    charset utf-8;

    //限制并发连接数,这里的“addr”是在前面的“ limit_conn_zone”中定义的,名称要保持一致

    limit_conn addr 5;

    #只允许我们的域名访问

    if ($host !~ ^(xxx.com|www.xxx.com|images.xxx.com)$ ) {

    return 444;

    }

    #屏蔽非法请求类型

    if ($request_method !~ ^(GET|HEAD|POST)$ ) {

    return 444;

    }

    #拒绝异常的User-Agents

    if ($http_user_agent ~* LWP::Simple|BBBike|wget) {

    return 403;

    }

    if ($http_user_agent ~* Sosospider|YodaoBot) {

    return 403;

    }

    #设置网站根目录

    root /usr/local/nginx/html;

    #设置默认首页

    index index.html index.htm index.php;

    include /etc/nginx/default.d/*.conf;

    #配置ssl证书

    ssl_certificate /etc/letsencrypt/live/xxx.com/fullchain.pem;

    ssl_certificate_key /etc/letsencrypt/live/xxx.com/privkey.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    ssl_prefer_server_ciphers on;

    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    location / {

    }

    location ^~ /static/{

    }

    #admin目录转交Tomcat处理

    location ~ /admin/ {

    proxy_pass http://tomcats;

    }

    #do、jsp等资源转交Tomcat处理

    location ~ .*.(do|jsp|action|jspx|shtml)?$ {

    proxy_pass http://tomcats;

    }

    #phpMyAdmin目录转交php处理

    location ~ /phpMyAdmin/ {

    fastcgi_index index.php;

    location ~ .*.(php|php5)?$ {

    #这里的9000端口是在/etc/php.ini中配置的,9000是默认值,你也可以修改

    fastcgi_pass 127.0.0.1:9000;

    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

    include fastcgi_params;

    }

    #/配置auth_basic验证

    auth_basic "security";

    #密码保存在哪里

    auth_basic_user_file /usr/local/nginx/conf/passwd;

    }

    error_page 404 /404.html;

    location = /40x.html {

    }

    error_page 500 502 503 504 /50x.html;

    location = /50x.html {

    }

    }

    }

    上面的配置文件中我们还调用了两个配置文件:proxy.conf、passwd。

    proxy.conf的内容如下:

    proxy_redirect off; #代理重定向关闭

    proxy_set_header Host $host; #从header头中获取的主机名

    proxy_set_header X-Real-IP $remote_addr;#获取header头中获取的主机的真实IP

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #获取header头中获取代理者的真实ip

    proxy_set_header X-Forwarded-Proto $scheme;

    server_names_hash_bucket_size 128;

    large_client_header_buffers 4 32k; #设置请求缓存

    client_header_buffer_size 64k; #客户端上传文件缓存大小

    client_max_body_size 300m; #设置客户端能够上传文件大小

    client_body_buffer_size 512k;

    proxy_connect_timeout 60; #跟后台服务器连接超时时间发起握手等待响应超时时间

    proxy_send_timeout 90; #后台服务器数据回传时间,就是在规定时间内后端服务器必须传完所有数据

    proxy_read_timeout 90; #连接成功后,等待服务器响应时间,其实已经进入后端的排队之中等待处理

    proxy_buffer_size 16k; #设置请求缓存区,这个缓存区会保存用户的头信息,以供nginx进行规则处理,一般只要能保存下头信息即可

    proxy_buffers 4 64k; #告诉nginx保留单个用到几个Buffer最大用多少空间

    proxy_busy_buffers_size 128k; #代理忙碌时使用的缓冲区大小

    proxy_temp_file_write_size 128k;#缓存临时文件的大小

    而passwd文件则要通过命令来生成:

    printf "admin:$(openssl passwd -crypt admin888) " >>/usr/local/nginx/conf/passwd

    上面的admin是用户名、admin888是密码。当我们访问http://xxx.com/phpMyAdmin的时候,将会先弹出以下提示,然后才进入正常的登陆界面。

    除了配置Nginx外,我们还要配置Tomcat。

    打开/usr/local/tomcat/conf/server.xml,在 节增加如下内容:

    remoteIpHeader="X-Forwarded-For"

    protocolHeader="X-Forwarded-Proto"

    protocolHeaderHttpsValue="https"/>

    这里顺便将Host的unpackWARs以及autoDeploy设置成false,主要是为了提高安全性。

    至此,所有配置完成,访问网站的时候可以看到URL位置有“安全连接”的提示:

    相关文章

      网友评论

        本文标题:搭建全功能服务器(Nginx+Tomcat+PHP+SSL)

        本文链接:https://www.haomeiwen.com/subject/jbckixtx.html