使用 NGINX 官方源安装,启动程序发现 Systemd 中存在报错:Can't open PID file /var/run/nginx.pid (yet?) after start: No such file or directory

● nginx.service - nginx - high performance web server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: active (running) since Thu 2020-12-10 03:35:04 MSK; 8s ago
     Docs: http://nginx.org/en/docs/
  Process: 9226 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS)
  Process: 9229 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
 Main PID: 9230 (nginx)
   CGroup: /system.slice/nginx.service
           ├─9230 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
           └─9231 nginx: worker process

Dec 10 03:35:04 vm228965.u83712.kvm.centos.7.64 systemd[1]: Stopped nginx - high performance web server.
Dec 10 03:35:04 vm228965.u83712.kvm.centos.7.64 systemd[1]: Starting nginx - high performance web server...
Dec 10 03:35:04 vm228965.u83712.kvm.centos.7.64 systemd[1]: Can't open PID file /var/run/nginx.pid (yet?) after start: No such file or directory
Dec 10 03:35:04 vm228965.u83712.kvm.centos.7.64 systemd[1]: Started nginx - high performance web server.

原因是Nginx 启动时 PID 文件并未生成,导致文件无法读取

知道问题如何产生,自然就有了解决办法。在 /usr/lib/systemd/system/nginx.service 中添加如下语句即可,作用是在执行可执行文件前等待 0.1s 。

ExecStartPost=/bin/sleep 0.1

添加后 /usr/lib/systemd/system/nginx.service 如下:

[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPost=/bin/sleep 0.1
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID

[Install]
WantedBy=multi-user.target

然后重新加载配置、启动

systemctl daemon-reload
systemctl restart nginx

问题修复。

可以新建一个ActionFilterAttribute来实现:

public class JsonCallbackAttribute : ActionFilterAttribute
{
    private const string CallbackQueryParameter = "callback";

    public override void OnActionExecuted(HttpActionExecutedContext context)
    {
        var callback = string.Empty;

        if (IsJsonp(out callback))
        {
            var jsonBuilder = new StringBuilder(callback);

            jsonBuilder.AppendFormat("({0})", context.Response.Content.ReadAsStringAsync().Result);

            context.Response.Content = new StringContent(jsonBuilder.ToString());
        }

        base.OnActionExecuted(context);
    }

    private bool IsJsonp(out string callback)
    {
        callback = HttpContext.Current.Request.QueryString[CallbackQueryParameter];

        return !string.IsNullOrEmpty(callback);
    }
}

使用例子:

[JsonCallback]
public IEnumerable<User> User()
{
    return _user;
}

1、安装最新的chrome dev包和字体以支持主要字符集(中文、日语、阿拉伯语、希伯来语、泰语和其他一些字符集)

apt-get update \
    && apt-get install -y wget gnupg \
    && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
    && apt-get update \
    && apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 libxtst6

关于国内无法访问 dl-ssl.google.com(被墙了)的解决方法:

把 https://dl-ssl.google.com/linux/linux_signing_key.pub 修改为本站提供的 https://down.24kplus.com/linux/google/linux_signing_key.pub 即可。

2、在部署 Puppeter 时可以指定路径,取消chromium下载(可选)

browser.launch({executablePath: 'google-chrome-stable'})

3、安装TTF-MSCoreFonts-Installer字体包(可选)

apt install cabextract libmspack0 xfonts-encodings xfonts-utils
wget http://httpredir.debian.org/debian/pool/contrib/m/msttcorefonts/ttf-mscorefonts-installer_3.8_all.deb
sudo dpkg -i ttf-mscorefonts-installer_3.8_all.deb

4、更新字体缓存

mkfontscale
mkfontdir
fc-cache -fv

解决执行 pecl upgrade-all 提示 Error getting channel info from pear.php.net: Connection to `ssl://pear.php.net:443' failed:Connection to 'ssl://pecl.php.net:443' failed: Unable to find the socket 错误。

出现这个错误主要是因为缺失默认证书导致的,具体原因不明。

下面说一下解决方案:

1、查看 default_cert_file 的路径

php -r "print_r(openssl_get_cert_locations());"

2、下载证书

wget -P /etc/ssl/ http://curl.haxx.se/ca/cacert.pem
chmod 744 /etc/ssl/cacert.pem

注意:其中 /etc/ssl/cacert.pem 替换为自己的真实路径

我们以Nginx 1.18.0为例子,手动编译升级Nginx,使Nginx支持HTTP2和TLS 1.3。

一、准备编译环境

1、检查 OpenSSL 版本

由于 TLS 1.3 需要 OpenSSL 1.1.1 或更高的版本支持,所以为了确保TLS1.3的正常运行,先检查 OpenSSL 版本

openssl version

OpenSSL 1.0.2k-fips 26 Jan 2017

如果低于 OpenSSL 1.1.1,请参考 https://www.24kplus.com/linux/97.html 升级 OpenSSL

2、安装依赖库

yum -y install libxml2 libxml2-devel libxslt-devel gd-devel gperftools libuuid-devel libblkid-devel libudev-devel fuse-devel libedit-devel libatomic_ops-devel gcc-c++

如果要启用 GeoIP2 模块,还需要安装 libmaxminddb;启用 IP2Location 模块需要安装 IP2Location C Library

3、获取上一次编译的参数

nginx -V

把红色框框的参数拷贝出来,后面会用到。

二、下载&编译&升级

1、下载解压

wget https://nginx.org/download/nginx-1.18.0.tar.gz
tar -xvf nginx-1.18.0.tar.gz
cd nginx-1.18.0

2、配置编译参数

把原版本编译参数(上面拷贝出来的)粘贴上去,如果 --with-http_v2_module 参数没有则在最后加入一行 --with-http_v2_module

./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib64/nginx/modules
......
--with-http_v2_module

3、编译

make

4、升级 Nginx

停止 Nginx 服务

systemctl stop nginx

备份旧版本 Nginx

注意:sbin实际路径可能和教程的不一样,具体路径看 nginx -V 命令输出的 --sbin-path 参数

cp /usr/sbin/nginx /usr/sbin/nginx.bak

拷贝新版本到 /usr/sbin

cp objs/nginx /usr/sbin/

开始升级 Nginx

make upgrade

最后,启动 Nginx

systemctl start nginx

5、检查升级结果

nginx -V

C# .NET Hallo world

要解决中文乱码问题,首先我们需要知道原因,一开始我尝试了gb2312,utf-8等多种编码格式导出,使用 Execl 打开均为乱码,后来无意中发现,必须为“带 BOM 的 UTF-8”。

代码示例:

using(var sw = new File.CreateText(fileName))
{
	sw .WriteLine(csvContent);
}

如果是asp.net页面输出,则为:

Response.Clear();
Response.Buffer = true;
Response.AppendHeader("Content-Disposition", "attachment;filename=" + DateTime.Now.ToShortDateString() + fileName + ".xls");
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.Charset = "utf-8";
Response.ContentType = "text/csv";
using(var outputWriter = new StreamWriter(Response.OutputStream, System.Text.Encoding.UTF8))
{
	outputWriter.WriteLine(csvContent);
}
Response.Flush();
Response.End();

1、准备编译环境

yum install autoconf automake libtool make gcc libwebp libwebp-devel -y

2、下载并解压

wget https://imagemagick.org/download/ImageMagick.tar.gz
tar -xzf ImageMagick.tar.gz
#注意:如果是CnetOS 8则需要输入完整路径
cd ImageMagick*

3、配置并编译

由于7.0之后的版本默认开启webp支持,所以不再需要 --with-webp 参数

./configure --prefix=/usr
make
sudo make install
ldconfig

4、PHP 安装 imagick 模块

pecl install imagick

会提示:Please provide the prefix of ImageMagick installation [autodetect] :,输入ImageMagick的安装路径:

/usr

回车,等待完成安装。

5、配置 imagick 模块

在php.ini文件加入一行

extension=imagick.so

然后重启 php-fpm,使 imagick 模块生效