Linux 设置环境变量

平时登录服务器经常会设置一些路径作为环境变量来提升工作效率,下面记录一下设置环境变量的各种方法。

Solution 1: 临时设置

使用 export 命令

export PATH="$PATH:/usr/local/bin"

查看是否生效

export

Solution 2: 修改 profile 文件

vim /etc/profile

# 在里面加入命令
export PATH="$PATH:$HOME/.local/bin:$HOME/bin:/usr/local/bin"

编辑完之后,运行命令生效

source /etc/profile 

Solution 3: 修改 .bashrc 文件

这种方法适用于设置不同账号不同的环境变量,一台服务器多个用户使用的话可以设置自己的环境变量。

# root 用户
vim /root/.bashrc

# 普通用户
vim /home/xxx/.bashrc

# 在里面加入命令
export PATH="$PATH:$HOME/.local/bin:$HOME/bin:/usr/local/bin"

修改完之后退出当前账号,重新登录系统,测试是否生效

echo $PATH

环境变量加载顺序

  1. /etc/profile
  2. /etc/environment
  3. ~/.bash_profile
  4. ~/.bashrc
  5. /etc/bashrc

解决登录linux环境后每次都要source /etc/profile使环境变量生效问题

1.编辑~/.bashrc文件

vim ~/.bashrc 

2.在末尾添加如下代码,保存

if [ -f /etc/profile ]; then
. /etc/profile
fi

php-fpm reload 时 nginx 出现 error log 分析

起因

每次 Jenkins 发版的时候 nginx 总会有几个 error log 出现,量也不是很大,通过时间点查看 access log,发现 http status 是 502。

2019/08/08 10:07:35 [error] 11346#0: *395555896 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 100.79.15.33, server: xxxxxx, request: "GET /api/v2/current-ad?language=zh_CN HTTP/1.1", upstream: "fastcgi://unix:/tmp/php-cgi-56.sock:", host: "xxxxxx"
2019/08/08 10:07:35 [error] 11347#0: *395557146 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 100.79.15.23, server: xxxxxx, request: "POST /hw/v2/scene/bundle/lists HTTP/1.1", upstream: "fastcgi://unix:/tmp/php-cgi-56.sock:", host: "xxxxxx"

解决方案

通过查找资料找到了需要配置的参数:

process_control_timeout = 10

参数含义是 设置子进程接受主进程复用信号的超时时间,控制子进程处理来自master的信号的时间,默认为 0 如果正在处理请求, 很可能会收到错误报警。

现在我们需要在 php-fpm.conf [global] 配置块里面配置,我这里配置为 10s,没有配置了 [global] 里面会导致 php-fpm 启动失败,切记!
配置完成之后需要 reload 加载最新配置,第一次 reload 还是会有 error 的,因为我们的配置还没有生效,之后的 reload 就可以解决此问题,这就可以放心的发版了!

Linux 平台安装 MongoDB

说明

MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。

步骤

1. 下载

https://www.mongodb.com/download-center/community
Version 选择最新的稳定版, OS 选择 Linux 64-bit legacy x64,会看到下载地址。

cd /usr/local/src
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.11.tgz

2. 解压

tar zvxf mongodb-linux-x86_64-4.0.11.tgz
mv mongodb-linux-x86_64-4.0.11 /usr/local/mongodb

3. 文件说明

Name Comments
bsondump 导出 bson 结构
install_compass compass 是一个 GUI 的管理工具
mongo 客户端(相当于 mysql.exe)
mongod 服务端(相当于 mysqld.exe)
mongodump 整体数据库导出(相当于 mysqldump)
mongofiles 操作 GridFS 文件
mongoreplay 重放流量到其他实例
mongos 路由器(分片时用)
mongotop 耗时数据统计
mongoexport 导出易识别的 json 或 csv,方便用代码处理
mongoimport 导入 json, csv 等格式
mongorestore 数据库整体导入,与 mongodump 相结合
mongostat instance 的状态统计,类似 vmstat

4. 启动

MongoDB 的可执行文件位于 bin 目录下,所以可以将其添加到 PATH 路径中:

export PATH= /usr/local/mongodb/bin:$PATH

MongoDB的数据存储在data目录的db目录下,但是这个目录在安装过程不会自动创建,所以你需要手动创建data目录,并在data目录中创建db目录。

mkdir -p /data/db

最简单的启动,前台运行

cd /usr/local/mongodb/bin
./mongo

后台运行

cd /usr/local/mongodb/bin
./mongod --dbpath /data/db --logpath /var/log/mongodb.log --logappend --fork --port 27017
Param Comments
--dbpath 数据存储目录
--logpath 日志存储目录
--port 运行端口(默认27017)
--fork 后台进程运行

5. 注意点

mongodb非常的占磁盘空间, 如果你用虚拟机练习,可能空间不够,导致无法启动.
可以用 --smallfiles 选项来启动,
将会占用较小空间 400M左右.

Linux统计文件夹、文件数量的命令

查看当前目录下的文件数量(不包含子目录中的文件)

ls -l|grep "^-"| wc -l

查看当前目录下的文件数量(包含子目录中的文件) 注意:R,代表子目录

ls -lR|grep "^-"| wc -l

查看当前目录下的文件夹目录个数(不包含子目录中的目录),同上述理,如果需要查看子目录的,加上R

ls -l|grep "^d"| wc -l

查询当前路径下的指定前缀名的目录下的所有文件数量

例如:统计所有以“20161124”开头的目录下的全部文件数量

ls -lR 20161124*/|grep "^-"| wc -l

  

对每个命令参数做一下说明备注:

ls -l
该命令表示以长列表输出指定目录下的信息(未指定则表示当前目录),R代表子目录中的“文件”,这个“文件”指的是目录、链接、设备文件等的总称

grep "^d"表示目录,"^-"表示文件

wc -l
表示统计输出信息的行数,因为经过前面的过滤已经只剩下普通文件,一个目录或文件对应一行,所以统计的信息的行数也就是目录或文件的个数

记一次 Laravel MethodNotAllowedHttpException 问题排查

问题描述

线上一个 laravel 4.2 的项目有 Exception 产生,通过查看 log 发现每天会有 2 条左右出现,量也不大,通过日志能看出是 MethodNotAllowedHttpException 异常,下面记录一下解决过程。

[2019-05-17 06:04:38] Oregon.ERROR: Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException in /******/endpoint/bootstrap/compiled.php:5753
Stack trace:
#0 /******/endpoint/bootstrap/compiled.php(5749): Illuminate\Routing\RouteCollection->methodNotAllowed(Array)
#1 /******/endpoint/bootstrap/compiled.php(5727): Illuminate\Routing\RouteCollection->getOtherMethodsRoute(Object(Illuminate\Http\Request), Array)
#2 /******/endpoint/bootstrap/compiled.php(5051): Illuminate\Routing\RouteCollection->match(Object(Illuminate\Http\Request))
#3 /******/endpoint/bootstrap/compiled.php(5039): Illuminate\Routing\Router->findRoute(Object(Illuminate\Http\Request))
#4 /******/endpoint/bootstrap/compiled.php(5031): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#5 /******/endpoint/bootstrap/compiled.php(720): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#6 /******/endpoint/bootstrap/compiled.php(696): Illuminate\Foundation\Application->dispatch(Object(Illuminate\Http\Request))
#7 /******/endpoint/bootstrap/compiled.php(7803): Illuminate\Foundation\Application->handle(Object(Illuminate\Http\Request), 1, true)
#8 /******/endpoint/bootstrap/compiled.php(8410): Illuminate\Session\Middleware->handle(Object(Illuminate\Http\Request), 1, true)
#9 /******/endpoint/bootstrap/compiled.php(8357): Illuminate\Cookie\Queue->handle(Object(Illuminate\Http\Request), 1, true)
#10 /******/endpoint/bootstrap/compiled.php(11154): Illuminate\Cookie\Guard->handle(Object(Illuminate\Http\Request), 1, true)
#11 /******/endpoint/bootstrap/compiled.php(657): Stack\StackedHttpKernel->handle(Object(Illuminate\Http\Request))
#12 /******/endpoint/public/index.php(48): Illuminate\Foundation\Application->run()
#13 {main} [] []

排查过程

  通过查找 nginx access log 找到对应的信息,是 post 请求 index.php,我用 postMan 来进行模拟并没有复现这个 exception,我拿到的只是一个 200 的 Response,并不是 500,这应该是扫描器批量扫描的,或者是 spider 爬的,并没有走域名,而是从 ip 直接访问。

**.93.2.** **.71.95.** 182.61.178.228 - "17/May/2019:06:04:39 +0800" "POST /index.php HTTP/1.1" 453 4534 0.680 500 unix:/tmp/php-cgi-72.sock - 0.004 "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:28.0) Gecko/20100101 Firefox/28.0" 

查找 nginx error log 没有对应的 log,问题到这里就僵住了,返回去看 exception log 找到抛出异常之前最后一个执行的方法

Illuminate\Routing\RouteCollection->getOtherMethodsRoute

/* 代码路径 */
/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php  :186
    /**
     * Get a route (if necessary) that responds when other available methods are present.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  array  $others
     * @return \Illuminate\Routing\Route
     *
     * @throws \Symfony\Component\Routing\Exception\MethodNotAllowedHttpException
     */
    protected function getOtherMethodsRoute($request, array $others)
    {
        if ($request->method() == 'OPTIONS')
        {
            return (new Route('OPTIONS', $request->path(), function() use ($others)
            {
                return new Response('', 200, array('Allow' => implode(',', $others)));

            }))->bind($request);
        }

        $this->methodNotAllowed($others);
    }

  看到这就大体明白了,如果 method 是 OPTIONS 会有 200 的正常 Response,否则就抛出错误,猜测 Http method 肯定是一个比较冷门的,导致框架报错,从 postMan 找一个比较冷门的 method UNLOCK 试了一下,果然状态 500,成功复现。

  这里有一段小插曲:为什么状态是 500 呢,应该是 405 才对,查看代码发现处理 error 的逻辑里面调用了一个已经优化掉的日志类,去掉那一行调用,一切正常。

- 阅读全文 -