关于项目访问的一些记录

张锋 4年前 访问:747 评论:0 关注:0

当访问域名后 解析nginx 配置文件

/home/service/nginx/conf/vhost]# cat happy.xxxxx.com.conf

首先 include common/header.conf; 文件中会定义变量

关键代码

反向代理到项目所在服务器

 # 接口
    location / {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
        add_header Access-Control-Allow-Headers accept,content-type,x-requested-with;

        if ($request_method = 'OPTIONS') {
            return 204;
        }

        proxy_store off;
        proxy_pass http://upstream_happy${var_virtual_host};
        proxy_set_header Scheme $var_scheme;
        proxy_set_header Host happy.xxx.com;
        proxy_set_header virtualhost $var_virtual_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Referer $http_referer;
        proxy_set_header X-Real_IP $remote_addr;
        client_max_body_size 35m;
        #####ADAPT#######
        proxy_set_header protocolflag $var_scheme;
        proxy_set_header rootflag $var_virtual_host;

        proxy_connect_timeout 5s;
        proxy_read_timeout 5s;
        proxy_send_timeout 5s;
    }

实际访问的目录为

/home/service/swoole/bin/swoole.sh 文件

#!/bin/sh
script="/home/service/swoole/lib/Server.php"
pidfile="/home/work/$2/var/swoole.pid"
pid=""

if [ -f "$pidfile" ]; then
    pid=$(cat $pidfile)
fi

start () {
    if [ -z "$pid" ]; then
        echo "Starting : begin"
        /home/service/php7/bin/php $script start $1
        echo "Starting : finish"
    else
        echo "Starting : running"
    fi
}

stop () {
    if [ -z "$pid" ]; then
        echo "Stopping : no master"
    else
        echo "Stopping : begin"
        /home/service/php7/bin/php $script stop $1
        pids=$(ps aux | grep Swoole | grep $1 | awk '$0 = $2')
        for pid in $pids ; do
            kill -9 $pid
        done
        echo "Stopping : finish"
    fi
}

case "$1" in
  start)
    start $2
    ;;
  stop)
    stop $2
    ;;
  *)
    echo $"Usage: $0 {start|stop} project"
    ;;
esac

而 sh 访问的主要文件为 两个

1./home/service/swoole/lib/Server.php

#!/home/service/php7/bin/php
<?php

require_once('RequestWorker.php');
require_once('JobTasker.php');

class Server {

    private $project = '.';

    //环境
    private $base = 'web';

    private $pidfile = 'var/swoole.pid';

    private $logPath = '/data/logs/prod_logs';

    private $pid = -1;

    protected $name = '';

    protected $server = null;

    protected $worker = null;

    protected $tasker = null;

    protected $config = [
        'host'    =>    '0.0.0.0',
        'port'    =>    8080,
        'reactor_num'    =>    2,
        'worker_num'    =>    1,
        'task_worker_num'    => 0,
        'max_conn'    =>    256,
        'max_request'    =>    5000,
        'dispatch_mode'    =>    2,
        'open_tcp_keepalive'    =>    1,
        'enable_static_handler'    =>    true,
        'http_parse_post'    =>    true,
        'document_root' => __DIR__,
    ];

    protected $appConfig = [];

    public static function createInstance($name, $path) {
        $instance = new self($name, $path);
        return $instance->init();
    }

    public static function attachInstance($name, $path) {
        $instance = new self($name, $path);
        return $instance->attach();
    }

    public function __construct($name, $path) {
        $this->name = $name;
        $this->project = $path;
        $this->base = $this->project . '/web';
        $this->pidfile = $this->project . '/var/swoole.pid';
        $this->logPath = '/data/logs/prod_logs';
    }

    public function attach() {
        $pid = $this->readPid();
        if($pid <= 0) {
            echo "服务实例未找到\n";
            return;
        }
        $this->pid = $pid;
        return $this;
    }

    public function start() {
        //配置服务
        $this->configServer();

        //启动服务
        $this->server->start();
    }

    public function stop() {
        \Swoole\Process::kill($this->pid, SIGTERM);

        file_put_contents($this->pidfile, '', LOCK_EX);
        unlink($this->pidfile);
        echo "Finish\n";
    }

    public function writePid() {
        file_put_contents($this->pidfile, $this->pid, LOCK_EX);
    }

    public function readPid() {
        if(!file_exists($this->pidfile)) {
            return 0;
        }
        $data = file_get_contents($this->pidfile);
        $pid = intval(trim($data));
        return $pid;
    }

    protected function init() {
        $pid = $this->readPid();
        if($pid > 0) {
            echo "服务正在运行中,无法启动多实例\n";
            return;
        }
        $this->config['log_file'] = $this->logPath . '/server.log';
        $this->config['document_root'] = $this->base;

        //读取容器配置
        $this->loadContainerConfig();
        return $this;
    }

    protected function configServer() {
        //读取项目配置
        $this->loadAppConfig();

        //服务对象
        $this->server = new \swoole_http_server($this->config['host'], $this->config['port']);
        $this->server->set($this->config);
        //master
        $this->configMaster();
        //manager
        $this->configManager();
        //worker
        $this->configWorker();
        //tasker
        $this->configTasker();
    }

    protected function configMaster() {
        $that = $this;
        $this->server->on('Start', function(Swoole\Server $server) use ($that){
            $ret = cli_set_process_title('Swoole Master ['. $that->name .']');
            $that->pid = $server->master_pid;
            $that->writePid();
            echo "Swoole Master -> [$ret]\n";
        });
    }

    protected function configManager() {
        $that = $this;
        $this->server->on('ManagerStart', function(Swoole\Server $server) use ($that) {
            cli_set_process_title('Swoole Manager ['. $that->name .']');
        });
    }

    protected function configWorker() {
        $that = $this;
        $this->server->on('WorkerStart', function(Swoole\Server $server, $workerId) use ($that){
            if($server->taskworker && $that->tasker) {
                cli_set_process_title('Swoole Tasker ['.$that->name.']');
                $that->tasker->start();
                return;
            }
            //worker
            cli_set_process_title('Swoole Worker ['.$that->name.']');
            $that->worker = $that->createWorker();
        });

        $this->server->on('WorkerStop', function(Swoole\Server $server, $workerId) use ($that){
            if($server->taskworker && $that->tasker) {
                $that->tasker->shutdown();
                return;
            }
        });

        //HTTP请求
        $this->server->on('Request', function(Swoole\Http\Request $request, Swoole\Http\Response $response) use ($that) {
            $that->worker->doRequest($request, $response);
        });
    }

    protected function configTasker() {
        if(!$this->config['task_worker_num']) {
            return;
        }
        $this->server->on('Task', function($server, $taskId, $fromId, $data){});
        $this->server->on('Finish', function($server, $taskId, $data) {});

        //tasker
        $tasker = new JobTasker($this->base, $this->name, $this->appConfig['Task']);
        $this->tasker = $tasker;
    }

    private function loadContainerConfig($configFile = 'swoole.ini') {
        if(strpos($configFile, '/') !== 0) {
            $configFile = $this->project . '/' . $configFile;
        }

        if(!file_exists($configFile)) {
            return;
        }

        $config = parse_ini_file($configFile, true);
        if(array_key_exists('swoole', $config)) {
            $server = $config['swoole']['server'];
            if(!array_key_exists($server, $config)) {
                return;
            }
            $config = $config[$server];
        }
        foreach($config as $k => $v) {
            $this->config[$k] = $v;
        }
    }

    private function createWorker() {
        $path = $this->base . '/gateways';
        $fd = opendir($path);
        if(!$fd) {
            return null;
        }

        $apps = [];
        while(($item = readdir($fd)) !== false) {
            if(strpos($item, '.') === 0) {
                continue;
            }

            $name = "$path/$item";
            if(!is_dir($name)) {
                continue;
            }
            $file = "$name/bootstrap/app.php";
            if(!file_exists($file)) {
                continue;
            }
            $app = require($file);
            $apps[$item] = $app;
            echo "Regist Application [$item] Success\n";
        }

        return new RequestWorker($this->base, $apps);
    }

    /**
    * 读取服务配置
    **/
    private function loadAppConfig($configFile = 'server.ini') {
        if(strpos($configFile, '/') !== 0) {
            $configFile = $this->base . '/' . $configFile;
        }

        if(!file_exists($configFile)) {
            return;
        }
        $config = parse_ini_file($configFile, true);
        $this->appConfig = $config;
        if(array_key_exists('Task', $config) && $config['Task']) {
            $this->config['task_worker_num'] = 1;
        }
    }
}

$argsCount = count($argv);
$script = $argv[0];
if($argsCount < 3 || !in_array($argv[1], ['start', 'stop', ])) {
    echo "Usage: $script {start|stop} project\n";
    exit(1);
}
$command = $argv[1];
$project = $argv[2];
$path = "/home/work/$project";
if(!file_exists($path)) {
    echo "项目[$project]不存在\n";
    exit(1);
}
if($command === 'start') {
    $instance = Server::createInstance($project, $path);
    if(!$instance) {
        exit(1);
    }
    $instance->start();
} else if($command === 'stop') {
    $instance = Server::attachInstance($project, $path);
    if(!$instance) {
        exit(1);
    }
    $instance->stop();
} else {
    echo "Usage: $script {start|stop} project\n";
    exit(1);
}

2.swoole.ini

[swoole]
server=happy

[happy]
host=0.0.0.0
port=23100
worker_num=24
max_conn=5000
max_request=5000
dispatch_mode=3
daemonize=1
backlog=2048
open_tcp_keepalive=1
tcp_defer_accept=5
open_tcp_nodelay=1
log_file=/data/logs/prod_logs/swoole.log
request_file=/data/logs/prod_logs/request.log
request_slowlog_timeout=3
request_slowlog_file=/data/logs/prod_logs/swoole_happy_php_slow.log
trace_event_worker=true
package_max_length=50000000

用swoole 启动了 http 服务 代替 PHP-FPM

原因有以下几点

1.fpm仅仅只是对节省了进程层级的开销,PHP的所有对象请求时创建,请求结束时全部销毁。对于普通PHP程序来说避免了内存泄漏。对于大型网站来说,这是严重的资源浪费

2.PHP-Server中每次请求仅销毁与请求相关的对象。与请求有关的全局对象都不需要销毁。直接在下次请求中复用。

3.APC/OpCache只能节省编译OpCode的时间,但OpCode还是要执行的。PHP-Server可以保留OpCode执行后的内存,节省资源。

4.PHPer可以操控的范围更⼤了,局部缓存,Once操作,写文件合并,统计数据合并,数据库连接,对象持久化,数据库连接池等都可以做。

评论

还没有人评论 ~

❤❤❤❤❤❤
心情
此图名叫《暗淡蓝点》
1990年2月14日,由旅行者1号拍摄,
蓝色的点就是地球
或许你看不清,因为地球在宇宙中太小了。