专栏首页后端技术探索几种web并行化编程实现

几种web并行化编程实现

当网站做到一定规模的时候,web单个页面需要涉及到的业务也会越来越多,每个页面可能会向后端发起几个、十几个甚至几十个请求。对于java、python之类的支持多线程的语言可以使用多线程编程,但也会增加程序的复杂性,像php这样的不支持多线程的语言只能借助其他方法实现并行,下面总结几种比较实用的并行化框架。

1、yar 是鸟哥开发的一个 基于php扩展的RPC框架。

[php] view plaincopy

  1. //service.php
  2. class ServiceTest
  3. {
  4. public function test($param){
  5. sleep(1);
  6. return 'sleep 1s';
  7. }
  8. public function test2($param){
  9. sleep(1);
  10. return 'sleep 1s';
  11. }
  12. public function test3($param){
  13. sleep(1);
  14. return 'sleep 1s';
  15. }
  16. }
  17. $service = new Yar_Server(new ServiceTest());
  18. $service->handle();
  19. //client.php
  20. $api = "http://127.0.0.1/yar/service.php";
  21. $param = array(1,2,3);
  22. function callback($retval, $callinfo){
  23. print_r($retval);
  24. }
  25. Yar_Concurrent_Client::call($api, 'test', array($param), 'callback');
  26. Yar_Concurrent_Client::call($api, 'test2', array($param), 'callback');
  27. Yar_Concurrent_Client::call($api, 'test3', array($param), 'callback');
  28. Yar_Concurrent_Client::loop();

上面服务端代码有3个方法都sleep一秒来模拟业务端的处理,通过yar扩展注册服务,client端通过Yar_Concurrent_Client并行请求这个三个方法,最终执行时间是大约是1s。值得一提yar的并行操作是通过libcurl的并行实现的,服务端代码必须能够通过http访问到。对于tpc和unix socket目前只能进行同步请求,如需要并行实现需要自行加入消息队列之内的东西去实现。

2、APS,是安居客集团以zmq为消息中间件,以事件驱动进行网络请求的一个跨语言RPC框架,框架中有一个代理(device)监听两个端口或本地socket文件,分别监听客户端发来的请求和转发给服务端的多个worker进程,并负责把woker处理返回的数据转发到客户端。运行github上面用php写的demon代码如下。

3、Gearman,是一个用来把工作委派给其他机器、分布式的调用更适合做某项工作的机器、并发的做某项工作在多个调用间做负载均衡、或用来在调用其它语言的函数的系统。通过worker向Gearmand守护进程注册工作,客户端通过Gearmand将任务分派到后端的worker进程,具体实现和APS类似。

4、nodejs,是一个事件驱动的单进程语言,可以通过这种异步编程模式实现对后台业务的并行处理。下面demo是以nodejs为客户端请求php后端的一个耗时3s的方法,一个耗时2s的方法:

[javascript] view plaincopy

  1. var http = require("http");
  2. var url = require('url');
  3. var eventProxy = require('eventproxy');
  4. var handle = {};
  5. handle['/'] = test;
  6. function start(route, handle) {
  7. function onRequest(request, response) {
  8. var pathname = url.parse(request.url).pathname;
  9. route(handle, pathname, response);
  10. }
  11. http.createServer(onRequest).listen(8081);
  12. }
  13. function route(handle, pathname, response){
  14. console.log("route\n");
  15. if (typeof handle[pathname] === 'function') {
  16. handle[pathname](response);
  17. } else {
  18. console.log(pathname + 'is no fund');
  19. }
  20. }
  21. function test(response) {
  22. var ep = new eventProxy();
  23. ep.all('data1', 'data2', function(a, b){
  24. response.writeHead(200, {"Content-Type": "text/plain"});
  25. response.write(a);
  26. response.write(b);
  27. response.end();
  28. });
  29. http.get('http://127.0.0.1/nodejs/service.php?function=test', function(data){
  30. var buffers = [], size = 0;
  31. data.on('data', function(buffer) {
  32. buffers.push(buffer);
  33. size += buffer.length;
  34. });
  35. data.on('end', function(){
  36. var buffer = new Buffer(size), pos = 0;
  37. for(var i = 0, l = buffers.length; i < l; i++) {
  38. buffers[i].copy(buffer, pos);
  39. pos += buffers[i].length;
  40. }
  41. ep.emit('data1', buffer);
  42. });
  43. });
  44. http.get('http://127.0.0.1/nodejs/service.php?function=test2', function(data){
  45. var buffers = [], size = 0;
  46. data.on('data', function(buffer) {
  47. buffers.push(buffer);
  48. size += buffer.length;
  49. });
  50. data.on('end', function(){
  51. var buffer = new Buffer(size), pos = 0;
  52. for(var i = 0, l = buffers.length; i < l; i++) {
  53. buffers[i].copy(buffer, pos);
  54. pos += buffers[i].length;
  55. }
  56. ep.emit('data2', buffer);
  57. });
  58. });
  59. }
  60. function sleep(milliSeconds) {
  61. var startTime = new Date().getTime();
  62. while (new Date().getTime() < startTime + milliSeconds);
  63. }
  64. start(route, handle);

总结:

上述并行请求的实现有两种方式,一是基于事件驱动模型nodejs、yar(yar底层libcurl的curl_multi应用select()),二是基于消息队列的多进程的任务调度APS、Gearman。在实际的应用中的选择什么样的并行框架可能会根据各个方面来抉择,不管选择哪个,带来的一个很大的好处是使程序SOA化,减小代码间的耦合度,更变方便扩展。

本文分享自微信公众号 - nginx(nginx-study)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2015-06-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 重磅!PHP之父Rasmus Lerdorf将出席2016中国php大会

    本猿获知PHP之父Rasmus Lerdorf将出席2016中国php大会并将发表技术分享后,内心激动不已,忍不住把这一消息分享给大家。

    后端技术探索
  • 后端前端恩仇录

    其实应该更多的是互相的磨合与学习,希望身边的人可以有自己的经验分享,与理解,互相进步才是大家需要的,作为一个 "年老" (我也是90后) 的开发者,我觉得一代胜...

    后端技术探索
  • 一边制造,一边讲解http状态码502|504|499|500

    Status Code 499、500、502、504也是后端Http服务经常返回的状态码,试想一下,对于每个状态码,如果你能通过一些修改或配置来人为复现它,是...

    后端技术探索
  • 一篇文章详解React Native初始化和通信机制

    开始准备写这一篇文章的时候,中国的新型冠状病毒肺炎疫情还在继续,累积确诊81058人,现存确诊10827人。这篇文章写完的时候,累计确诊81501人,现存确认5...

    VV木公子
  • 博客园美化博客随笔目录

    小小咸鱼YwY
  • UAF Writeup - pwnable.kr

    0x00 UAF — pwnable.kr是一个韩国的CTF练习的网站,有很多经典的CTF题目供爱好者练习。 UAF(Use After Free)释放后重用...

    xfkxfk
  • Kibana源码剖析 —— savedSearch从读取到跳转

    持久化对象 Kibana中可以查询到很多保存的对象,他们都存储在es中一个叫做.kibana的索引中。 搜索 存储在type为search中; 图表 存储在ty...

    用户1154259
  • IOS系统下虚拟键盘遮挡文本框问题的解决

    最近在项目中发现同样的代码在Android端微信网页中点击文本框唤出的虚拟键盘不会遮挡文本框,但是在IOS端的微信网页中点击文本框唤出的键盘却在大部分情况下会遮...

    lin_zone
  • JQuery 小结

    1。文本框的改变事件,可使用propertychange,例如: $("#txtDataDate").bind("propertychange",fu...

    hbbliyong
  • Maven异常_04_Failed to clean project

    异常:Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean ...

    shirayner

扫码关注云+社区

领取腾讯云代金券