dubbo-php-framework的TcpServer解析(一)

版权声明:转载请注明来源 https://blog.csdn.net/u013702678/article/details/82721456

在之前文章中解析provider_admin的start流程时,分析到了最终调用TcpServer的run方法启动Provider应用。这篇开始我们分析TcpServer的相关方法和核心流程体系,TcpServer代码位于dubbo-php-framework-master/provider/core/server/TcpServer.php中。

从TcpServer的继承体系可以看出,TcpServer->BaseServer->IServer,这些类的定义都在和TcpServer同一个目录中,我们按模块的复杂度分析,首先我们分析下IServer。

//核心模块都使用了命名空间,比较规范
namespace com\fenqile\fsof\provider\core\server;

//声明接口
interface IServer
{
    function run($setting);
    function send($client_id, $data);
    function close($client_id);
    function setProtocol($protocol);
    //当前app是否提供了满足条件的服务
    function serviceExist($serviceName,  $group, $version);
    //获取app中满足条件的服务实例,一个app提供的所有服务都以单实例的形式存于内存中
    function getServiceInstance($serviceName,  $group, $version);
    //获取app的监控器
    function getAppMonitor();
}
//申明命名空间
namespace com\fenqile\fsof\provider\core\server;

//TcpServer继承自BaseServer
class TcpServer extends BaseServer
{    
    public function init() 
    {
        //设置Swoole服务器网络通信模块,这里声明为Tcp类型
        $this->sockType = SWOOLE_SOCK_TCP;
        
        //设置Swoole Server的属性信息,这里设置为关闭Tcp nodelay算法
        $setting = array(
		    'open_tcp_nodelay' => 1,
        );
        
        $this->setting = array_merge($this->setting, $setting);
    }
}

BaseServer的实现过程牵涉模块较多,我们按provider_admin模块中start的过程进行解析,对于剩下的流程单独进行解析,流程如下图代码所示。

$server = new TcpServer($name);
//加载app root目录下的bootstrap.php和provider/$name.provider文件
$server->setRequire(FSOFConfigManager::getProviderAppRoot($name));

//app/conf目录下的$name.deploy文件
$server->loadConfig($config);
//全局fsof.ini文件
$server->loadConfig(FSOFConfigManager::getFSOFIni());

//设置swoole扩展日志文件
$server->setSwooleLogFile($cmd);

//provider启动时初始化consumer
$server->initConsumer();

//初始化server资源
$server->initRunTime('/var/fsof/provider');

//启动
$server->run($cmd);

BaseServer代码量较大,这篇我们只解析BaseServer的构造函数过程(这块开源的代码注释较好,我没自己分析,请谅解),其他的在后面篇章分开讨论。

namespace com\fenqile\fsof\provider\core\server;

use com\fenqile\fsof\common\log\FSOFSystemUtil;
use com\fenqile\fsof\common\file\FileSystemUtil;
use com\fenqile\fsof\common\config\FSOFConstants;
use com\fenqile\fsof\common\config\FSOFConfigManager;
use com\fenqile\fsof\common\protocol\fsof\DubboParser;
use com\fenqile\fsof\common\protocol\fsof\DubboResponse;
use com\fenqile\fsof\consumer\FSOFConsumer;
use com\fenqile\fsof\provider\common\Console;
use com\fenqile\fsof\provider\core\app\AppLauncher;
use com\fenqile\fsof\provider\core\app\AppContext;
use com\fenqile\fsof\provider\core\protocol\IProtocol;
use com\fenqile\fsof\provider\monitor\AppMonitor;
use com\fenqile\fsof\provider\monitor\OverloadMonitor;

abstract class BaseServer implements IServer
{
	//定义过载默认参数
    const FSOF_SWOOLE_WAITING_TIME_MS = 1500;
    const FSOF_SWOOLE_OVERLOAD_NUM_INAROW = 5;
    const FSOF_SWOOLE_LOSS_NUM_INAROW = 20;

    protected $sw;
    protected $processName = 'ProviderServer';
    protected $host = '0.0.0.0';
    protected $port = 9527;
    protected $listen;//监听ip与端口号的array
    protected $mode = SWOOLE_PROCESS;
    protected $sockType;

    protected $config = array(); //服务的配置信息
    protected $setting = array();//swoole_server配置
    protected $runPath = '/var/fsof/provider';
    protected $masterPidFile;
    protected $managerPidFile;
    protected $user = 'root';

    protected $protocol;

    protected $rootFile = '';  //deploy中root路径
    protected $deployVersion = NULL;//provider发布版本
    protected $requireFile = '';  //provider启动文件
	protected $serverProviders = NULL;   //服务提供者信息
    protected $appContext;		  //服务提供者存储容器

    //当发生shutdown时,将错误信息回传给client
    protected $cur_fd = -1;
    protected $cur_from_id = -1;
	protected $request = array();
	
	protected $start_without_registry = false;

	//app过载监控对象
	protected $overloadMonitor;

    private $logger;
	
	public function __construct($name = 'ProviderServer')
	{
        $this->logger = \Logger::getLogger(__CLASS__);
		$this->processName = $name;
		
        // Initialization server startup parameters
        $this->setting = array(
            'worker_num' => 4,     //PHP代码中是全异步非阻塞,worker_num配置为CPU核数的1-4倍即可。如果是同步阻塞,worker_num配置为100或者更高,具体要看每次请求处理的耗时和操作系统负载状况
        	'max_request' => 5000, //表示worker进程在处理完n次请求后结束运行,设置为0表示不自动重启。在Worker进程中需要保存连接信息的服务,需要设置为0.
            'dispatch_mode' => 3,   // 1平均分配,2按FD取摸固定分配,3抢占式分配,默认为取摸(dispatch=2)
            'task_worker_num' => 0, // task process num
        	'task_max_request' =>5000,
        	'task_ipc_mode' =>3,	//1 使用unix socket通信 , 2使用消息队列通信, 3使用消息队列通信,并设置为争抢模式,此时task/taskwait将无法指定目标进程ID
        	
        	'max_conn' => 10000,  // 设置Server最大允许维持多少个tcp连接,max_connection默认值为ulimit -n的值为1024,通过ulimit -n 65535更改最大默认值
        	'daemonize' => TRUE,    // 是否开启守护进程
        	'work_mode' => 3,		// 1 base模式,2线程模式,3进程模式				
			
        	//协议包长度检测,以保证onReceive函数接收到的数据是个完整的包,并且包的最大长度为2M
        	'open_length_check' => TRUE,
        	'package_length_offset' => 12,
        	'package_body_offset' => 16,
        	'package_length_type' => 'N',
        	'package_max_length' =>1024*1024*2,
        
			//启用心跳检测,此选项表示每隔多久轮循一次,单位为秒
        	'heartbeat_idle_time' => 600,
        	'heartbeat_check_interval' => 60,
        
	        //TCP-Keepalive死连接检测,如果对于死链接周期不敏感或者没有实现心跳机制,可以使用操作系统提供的keepalive机制来踢掉死链接
	        'open_tcp_keepalive' => 1,          // 表示启用tcp keepalive
	        'tcp_keepidle' => 600,               // 单位秒,连接在n秒内没有数据请求,将开始对此连接进行探测
	        'tcp_keepcount' => 3,               // 探测的次数,超过次数后将close此连接。
	        'tcp_keepinterval' => 10,            // 探测的间隔时间,单位秒。
        );

        $this->setHost();
        $this->init();
	}

猜你喜欢

转载自blog.csdn.net/u013702678/article/details/82721456
今日推荐