存档

2013年11月 的存档

为什么选择swoole?

2013年11月25日 没有评论

Golang

golang很不错,性能好,开发效率高。协程+通道既解决了异步IO,又解决了并行问题。但Go目前存在gc和协程调度的问题,Java之类语言花了近20年的时间来完善GC,GO估计3-5年之内很难解决。同样node.js也存在此问题。

gc问题:golang和node.js都是定期进行全局gc,当发生gc时,所有代码都停止运行。如果内存申请释放很复杂,需要很长的时间才能处理完毕。程序会发生周期性卡顿。
协程调度:golang是编译为机器码执行的,如果某个协程占用的cpu时间过长,其他协程会得不到执行。这和erlang不同,erlang是运行在VM之上的,VM可以自己进行调度。机器码调度只能靠CPU中断,而且一般只有操作系统有调度的权力。Golang中只能依赖手工在代码中加入Yield(),转让CPU时间片。

Node.js

单进程单线程,全异步,性能很好。但应用层不能有阻塞,需要写大量嵌套回调才能实现业务逻辑。开发者心智负担太高。随着业务代码增加,开发和维护越来越困难。

Erlang

erlang也是协程+通道,和golang相同。Erlang确实是网络编程的终极方案,而且erlang是基于VM执行的,不存在golang的2个问题。erlang是函数式编程,比较难入门,开发效率不高。

php+libevent

libevent只是一个事件轮询的库,epoll的封装。libevent过于底层,不是整套方案,你需要自行写大量底层代码。维护成本很高,另外一旦出了问题,你需要非常熟悉libevent才能解决。

Swoole

swoole与node.js/react之类不同的是,swoole是整体方案。从性能、异步、并行、可维护性、开发效率方面综合考虑的。swoole中你可以同步,也可以异步。代码中可以有阻塞,通过多开进程来调整处理能力。

既保证性能,又保证开发效率。

分类: Swoole扩展 标签:

Java是严谨的编程语言吗?

2013年11月12日 1 条评论

未必。就拿对象属性来说。在java里是直接写名称来用,直接xxx,这点和C++一样。而PHP是通过 this.xxx来调用。

Java代码:


public class Test
{
   private int xxx;
   public static void main(String[] args)
   {
       xxx = 12345;
   }
}

PHP代码:


class Test
{
    private $xxx;
    function main()
    {
        $this->xxx = 12345;
    }
}

Java/C++这样的语法,显然不好区分哪个是局部变量,哪个是对象属性。而PHP就一目了然了。

分类: C/C++, Java 标签:

PHP实现真正的异步MySQL

2013年11月7日 1 条评论

node.js之类的语言可以实现异步的数据库查询功能,执行SQL语句之后不必等待数据库返回结果。继续去执行其他的代码,当数据库返回结果是再对数据进行处理,如渲染页面,并将HTML页面发送给客户端。这样应用程序完全不需要阻塞等待。这种方式运行效率非常高。

PHP中是否可以实现类似的异步非阻塞MySQL查询呢?使用github搜索发现一个项目貌似是做此功能的,https://github.com/kaja47/async-mysql,查看代码是基于React.PHP.的。但并不是真正的异步SQL。实现的原理是设置一个定时器,每0.02秒轮询一次。虽然也可以用,但这样很浪费CPU资源。不是真正的异步MYSQL。

现在Swoole1.6.2提供了swoole_event_add和swoole_get_mysqli_sock 2个新的函数,使用它完全可以实现真正的PHP异步MySQL。下面讲一下具体的实现。

代码:


$db = new mysqli;
$db->connect('127.0.0.1', 'root', 'root', 'test');
$db->query("show tables", MYSQLI_ASYNC);
swoole_event_add(swoole_get_mysqli_sock($db), function($db_sock) {
global $db;
$res = $db->reap_async_query();
var_dump($res->fetch_all(MYSQLI_ASSOC));
swoole_event_exit();
});

首先连接mysql,连接成功后执行SQL语句,要在第二个参数指定MYSQLI_ASYNC。表示此查询为异步。query函数会立即返回,这时候并没有得到mysqli_result。

然后调用swoole_get_mysqli_sock函数取到mysql连接的socket,并调用swoole_event_add将它加入到swoole的epoll事件循环中。当数据库返回结果是会回调我们刚才制定的函数。

这时候再调用mysqli_reap_async_query得到result,调用fetch_all函数得到数据。

这个过程是完全异步非阻塞的,不存在任何浪费CPU的代码。这个代码还可以用在服务器端程序上,具体代码实现后续会再写一篇文章详细介绍。

 

分类: PHP, Swoole扩展 标签: