ubuntu 18.04完整安装配置WordPress 5.5.3并调优

$ sudo apt-get install apache2

$ sudo apt-get install mysql-server

$ sudo apt-get install mysql-client

$ sudo apt-get install php7.2

$ sudo apt-get install php-gd

$ sudo apt install php-mbstring

$ sudo apt install php-dom

# 如果使用了WP-Statistics统计插件,需要安装依赖
$ sudo apt-get install php7.2-curl

$ sudo apt-get install php7.2-bcmath

# PHP Zip支持,提高网络以及内存压缩工具,提升性能
$ sudo apt-get install php-zip

# PHP图像处理支持,imagick替代默认的GD图像处理,提升图像处理性能
$ sudo apt install php-imagick

# 默认imagick是不启用的,需要手工开启
$ sudo phpenmod imagick

$ sudo a2dismod mpm_prefork

$ sudo a2enmod mpm_event

$ sudo apt-get install libapache2-mod-fastcgi php7.2-fpm

$ sudo service php7.2-fpm restart

$ sudo a2enmod actions fastcgi alias proxy_fcgi

$ sudo apt-get install php-mysql

# 启用 Rewrite 模块,我们后续的WP Super Cache需要这个模块的支持
$ sudo a2enmod rewrite

$ sudo service apache2 restart

# 我们以root连接数据库,我们需要手工创建数据库,否则会出现如下错误:
# “我们能够连接到数据库服务器(这意味着您的用户名和密码正确),但未能选择wordpress数据库。”
$ mysql -u root -p -e "create database wordpress;" 

$ cd /var/www

$ sudo chown -R www-data:www-data wordpress

WordPress配置文件

<VirtualHost *:80>
	# The ServerName directive sets the request scheme, hostname and port that
	# the server uses to identify itself. This is used when creating
	# redirection URLs. In the context of virtual hosts, the ServerName
	# specifies what hostname must appear in the request's Host: header to
	# match this virtual host. For the default virtual host (this file) this
	# value is not decisive as it is used as a last resort host regardless.
	# However, you must set it for any further virtual host explicitly.
	#ServerName www.example.com

	ServerAdmin webmaster@localhost
	#DocumentRoot /var/www/html
	DocumentRoot /var/www/wordpress
	<Directory /var/www/wordpress>
		#Options Indexes FollowSymLinks MultiViews
		Options FollowSymLinks MultiViews
		AllowOverride All
#		Apache 2.2 
#		FCGIWrapper /usr/bin/php5-cgi .php
#		AddHandler fcgid-script .php
#               Options ExecCGI SymLinksIfOwnerMatch
#		Apache 2.4.10
		<FilesMatch \.php$>	
			SetHandler "proxy:unix:/run/php/php7.2-fpm.sock|fcgi://localhost"
		</FilesMatch>
		Order allow,deny
		allow from all
	</Directory>

	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
	# error, crit, alert, emerg.
	# It is also possible to configure the loglevel for particular
	# modules, e.g.
	#LogLevel info ssl:warn

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	# For most configuration files from conf-available/, which are
	# enabled or disabled at a global level, it is possible to
	# include a line for only one particular virtual host. For example the
	# following line enables the CGI configuration for this host only
	# after it has been globally disabled with "a2disconf".
	#Include conf-available/serve-cgi-bin.conf
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

启用`Apache2`的`cache`,`expire`,`gzip`模块,加强服务器性能

$ sudo a2enmod cache

$ sudo a2enmod expires

$ sudo a2enmod deflate

$ sudo service apache2 restart

PHP-FPM进程数的设定,提高响应速度,解决页面加载时候缓慢的问题(如果感觉打开页面缓慢,建议调整下面的配置,这种情况尤其在访问量不大的时候会出现短暂的耗时增大,原因就是php进程被临时创建导致延迟增大

# 增大最大并发进程数量,默认为5 根据需要增大
$ sudo sed -i "s/^pm.max_children = 5/pm.max_children = 20/g" /etc/php/7.2/fpm/pool.d/www.conf

# 增大系统启动初始化的进程数量,默认为 1 根据需要增大
$ sudo sed -i "s/^pm.start_servers = 1/pm.start_servers = 10/g" /etc/php/7.2/fpm/pool.d/www.conf

# 增大保留的最低空闲进程数量,默认为 2 根据需要增大
$ sudo sed -i "s/^pm.min_spare_servers = 2/pm.min_spare_servers = 10/g" /etc/php/7.2/fpm/pool.d/www.conf

# 增大保留的最高空闲进程数量,默认为 3 根据需要增大
$ sudo sed -i "s/^pm.max_spare_servers = 3/pm.max_spare_servers = 20/g" /etc/php/7.2/fpm/pool.d/www.conf

# 配置进程在处理多少个请求之后就退出,避免某些操作导致内存泄漏,及时进行资源回收操作
$ sudo sed -i "s/^#pm.max_requests = 500/pm.max_requests = 5000/g" /etc/php/7.2/fpm/pool.d/www.conf

启用PHP7的opcache配置

######避免PHP信息暴露在http头中
expose_php = Off

######在关闭display_errors后开启PHP错误日志(路径在php-fpm.conf中配置)
log_errors = On

######开启opcache
[opcache]
; Determines if Zend OPCache is enabled
;opcache.enable=0
opcache.enable=1

; The OPcache shared memory storage size.
;opcache.memory_consumption=128
opcache.memory_consumption=256

; The maximum number of keys (scripts) in the OPcache hash table.
; Only numbers between 200 and 1000000 are allowed.
;opcache.max_accelerated_files=10000
opcache.max_accelerated_files=1000000

; When disabled, you must reset the OPcache manually or restart the
; webserver for changes to the filesystem to take effect.
;opcache.validate_timestamps=1
opcache.validate_timestamps=3000

重启服务

$ sudo service php7.2-fpm restart

参考链接


HttpClient利用MultipartEntityBuilder取代MultipartEntity上传图片文件到服务器

注意:在HttpClient4.3之后,原来的上传文件方法MultipartEntity已经不建议使用,现替换成新的httpmime下面的MultipartEntityBuilder。

需要添加httpclient-4.5.jar、httpmime-4.5.jar两个包

maven添加:

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5</version>
        </dependency>

下面我们对比一下MultipartEntity和MultipartEntityBuilder的使用区别:

MultipartEntityBuilder:

             //传入参数可以为file或者filePath,在此处做转换
            File file = new File(filePath);
            CloseableHttpClient httpClient = HttpClients.createDefault();
            CloseableHttpResponse httpResponse = null;
            HttpPost httppost = new HttpPost(url);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            //设置浏览器兼容模式
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            //设置请求的编码格式
            builder.setCharset(Consts.UTF_8);
            builder.setContentType(ContentType.MULTIPART_FORM_DATA);
            //添加文件
            builder.addBinaryBody("file", file);
            HttpEntity reqEntity = builder.build();
            httppost.setEntity(reqEntity);

            httpResponse = httpClient.execute(httppost);

MultipartEntity:

            //传入参数可以为file或者filePath,在此处做转换
            File file = new File(filePath);
            CloseableHttpClient httpClient = HttpClients.createDefault();
            CloseableHttpResponse httpResponse = null;
            HttpPost httppost = new HttpPost(url);
            FileBody filebody = new FileBody(file);
            MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, null,
                    Charset.forName("UTF-8"));
            entity.addPart("file", filebody);
            httppost.setEntity(entity);

直接上替换后的测试代码:

package com.test.util;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;

public class HttpPostUploadUtil {

    /**
     * @param args
     */
    public static void main(String[] args) {
        String filePath = "D:\\Test\\0.jpg";
        String url = "http://127.0.0.1:8080/FastFds";
        //调用上传方法
        String backInfo = uploadPost(url, filePath);
        if(StringUtils.isNotBlank(backInfo)){
            //转json数据
            JSONObject json = JSONObject.fromObject(backInfo);
            if(!json.isEmpty()){
                //数据处理
                String value = json.getString("test");
                System.out.println(value);
            }
        }
    }

    /**
     * 上传图片/文件
     * @param url
     * @param filePath
     * @return String 用于转json或者其他信息
     */
    public static String uploadPost(String url, String filePath)  {
        String requestJson = "";
        //传入参数可以为file或者filePath,在此处做转换
        File file = new File(filePath);

        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse = null;
        try {
            HttpPost httppost = new HttpPost(url);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            //设置浏览器兼容模式
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            //设置请求的编码格式
            builder.setCharset(Consts.UTF_8);
            builder.setContentType(ContentType.MULTIPART_FORM_DATA);
            //添加文件
            builder.addBinaryBody("file", file);
            HttpEntity reqEntity = builder.build();
            httppost.setEntity(reqEntity);

            httpResponse = httpClient.execute(httppost);
            int backCode = httpResponse.getStatusLine().getStatusCode();
            if(backCode == HttpStatus.SC_OK){
                HttpEntity httpEntity = httpResponse.getEntity();
                byte[] json= EntityUtils.toByteArray(httpEntity);
                requestJson = new String(json, "UTF-8");
                //关闭流
                EntityUtils.consume(httpEntity);
                return requestJson;
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //释放资源
            try {
                httpClient.close();
                httpResponse.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return null;
    }
}

继续阅读HttpClient利用MultipartEntityBuilder取代MultipartEntity上传图片文件到服务器