服务器程序源代码分析之二:php-fpm

服务器程序源代码分析之二:php-fpm,第1张

php作为排名top2 互联网开发工具,非常流行,可以参考:中国最大的25个网站采用技术选型方案

php这个名称实际上有两层含义

直接定义:

php-fpm从php5.3.3开始已经进入到php源代码包,之前是作为patch存在的

很少人会去读php本身源代码,我6年前解决php内存泄露问题的时候做了些研究,最近再查看了一番,发现php的开发者很有诚意,这是一款非常出色的服务器软件,支持如下

在linux服务器上,如果不设置 events.mechanism ,那么默认就是采用epoll,所以

php-fpm的IO模型&并发处理能力和nginx是完全一致

nginx以性能卓越闻名,大部分程序员都认为php效率低下,看了源代码,才知道这是传奇啊

在高性能部署的时候,大家往往会针对性的优化nginx 。我自己之前部署php程序也犯了错误,8G内存的server,php-fpm的max children都会设置128+,现在看来太多了,参考nginx的部署:

php-fpm配置为 3倍 cpu core number就可以了

php-fpm稳定性比nginx稍差 这是因为php-fpm内置了一个php解析器,php-fpm进程就和php程序捆绑了,如果php脚本写得不好,有死循环或者阻塞在某个远端资源上,会拖累加载它的php-fpm进程

而nginx和后端应用服务器之间通过网络连接,可以设置timeout,不容易堵死则渣的

php-fpm的fastcgi是短连接 我原以为是长连接的,看了代码才知道也是短连接,处理一个request就关闭掉

php-fpm接口采用fastcgi 非常遗憾,php-fpm和fastcgi完全绑定了,无法独立使用 。只能部署在支持http-fcgi协议转换程序背后(nginx)。其实可以考虑在php-fpm代码包里面引入http协议支持,这样php-fpm可以独立运行,让nodejs无话可说

php-fpm等同于OpenResty OpenResty是一个国人开发的nginx模块,就是在nginx引入漏拦lua解释器. 实际上,它和php-fpm的唯一差别就是一个采用php语法,一个用lua,所以OpenResty要作为nginx增强包使用还可以,要选择它作为一个主要编程工具,没有任何返盯胡必要

从架构上来说,php-fpm已经做到最好,超过大多数 python部署工具,我再也不黑它了

一、概述

走入Eclipse的内核,看看它到底是怎么工作的?

1、Eclipse源如态代码

下载地址:http://download.eclipse.org/eclipse/downloads

2、源代码阅读工具

Source Insight

V3.5

它其实是一个代码编辑软件,因为有强大的代码分析工具,可以很方便地跟踪代码的相关性,所以常用来作为阅读代码的工具。

下载地址:http://sourceinsight.com/down35.html

为了方便代码的分析,我们只提取以下几个插件的代码:

org.eclipse.platform

org.eclipse.platform_3.1.1.jar

org.eclipse.core.commands

org.eclipse.core.commands_3.1.0.jar

org.eclipse.core.expressions

org.eclipse.core.expressions_3.1.0.jar

org.eclipse.core.runtime

org.eclipse.core.runtime_3.1.1.jar

org.eclipse.help

org.eclipse.help_3.1.0.jar

org.eclipse.jface

org.eclipse.jface_3.1.1.jar

org.eclipse.osgi

org.eclipse.osgi_3.1.1.jar

org.eclipse.swt.win32.win32.x86

org.eclipse.swt.win32.win32.x86_3.1.1.jar

org.eclipse.swt

org.eclipse.swt_3.1.0.jar

org.eclipse.ui.workbench

org.eclipse.ui.workbench_3.1.1.jar

org.eclipse.ui

org.eclipse.ui_3.1.1.jar

org.eclipse.update.configurator

org.eclipse.update.configurator_3.1.0.jar

将这些代码解压缩到一个空目录里,然后导入到Source

Insight的Project里。

二、Eclipse启动过程

首先我们从Eclipse的启动过程开始滑雹分析。

1、eclipse.exe

它是Eclipse的启动文件,是与平台相关的可执行文件。它的功能比较简单,主要是加载startup.jar文件,代码在Eclipse源代码的/features/org.eclipse.platform.launchers/library目录下,对应多个平台。对于win32平台,你可以直接运行win32目录下的build.bat文件来编译得到它(需要安装C编译器)。

2、startup.jar

这个是Eclipse真正的启动文件,你可以在命令行下运行java

-jar

startup.jar命令来信橡帆启动Eclipse。它的入口是org.eclipse.core.launcher.Main,它对应的源代码在org.eclipse.platform/src目录的子目录下的Main.java。我们从main函数往后跟踪,找到basicRun,这个是启动的主要部分。

protected

void basicRun(String[] args) throws Exception {

......

setupVMProperties() //设置VM属性

processConfiguration()//读取configuration/config.ini配置文件

......

// need to ensure that getInstallLocation is called at least

once to initialize the value.

// Do this AFTER processing the

configuration to allow the configuration to set

// the install

location.

getInstallLocation()

// locate boot

plugin (may return -dev mode variations)

URL[] bootPath =

getBootPath(bootLocation)

setSecurityPolicy(bootPath)

//设置执行权限

// splash handling is done here, because the default

case needs to know

// the location of the boot plugin we are going to

use

handleSplash(bootPath)

invokeFramework(passThruArgs, bootPath) //启动Eclipse内核

}

这个函数前面部分是设置一些属性,最关键的是最后invokeFramework函数,它是启动Eclipse的核心。下面我们看看invokeFramework函数的具体内容。

private

void invokeFramework(String[] passThruArgs, URL[] bootPath)

throws

ClassNotFoundException, NoSuchMethodException, IllegalAccessException, Error,

Exception, InvocationTargetException {

......

URLClassLoader loader = new StartupClassLoader(bootPath, parent)

Class clazz = loader.loadClass(STARTER)//加载

String STARTER =

"org.eclipse.core.runtime.adaptor.EclipseStarter"

Method method =

clazz.getDeclaredMethod("run", new Class[] {String[].class,

Runnable.class}) //获得run方法

......

method.invoke(clazz, new Object[] {passThruArgs, endSplashHandler})

//调用run方法

......

}

首先创建加载器loader,它是一个URLClassLoader类型。接着加载类"org.eclipse.core.runtime.adaptor.EclipseStarter",获得其run方法,然后调用此方法。

3、OSGI启动

"org.eclipse.core.runtime.adaptor.EclipseStarter"类的源代码位于/plugins/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor。可见它已经位于OSGI包内,它是OSGI的启动类。

public

static void startup(String[] args, Runnable endSplashHandler) throws Exception

{

......

adaptor = createAdaptor() //建立适配器

......

OSGi osgi = new OSGi(adaptor) //建立OSGI对象,这就是我们要找的东西

......

osgi.launch() //启动OSGI

......

context = osgi.getBundleContext() //获得已加载的Bundle的执行上下文

......

Bundle[] startBundles = loadBasicBundles() //加载Bundle

setStartLevel(getStartLevel()) //设置启动级别

......

}

4、Eclipse固定菜单的实现类(如Project、Help等菜单)

org.eclipse.ui.internal.ide包下的WorkbenchActionBuilder.java类中的 protected void

fillMenuBar(IMenuManager menuBar)方法,具体实现如下:

protected void

fillMenuBar(IMenuManager menuBar) {

menuBar.add(createFileMenu())

//在菜单栏增加File菜单

menuBar.add(createEditMenu())

menuBar.add(createNavigateMenu())

menuBar.add(createProjectMenu())

menuBar.add(new

GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS))

menuBar.add(createWindowMenu())

menuBar.add(createHelpMenu())

}

如果想去掉File菜单下的Move项可以注掉private

MenuManager createFileMenu()方法中的以下语句:

// menu.add(moveAction)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12298555.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存