微服务之使用NodeJS创建HTTP代理服务器(反向代理)
微服务 MicroService nodejs http 反向代理    2017-07-19 20:20:45    945   

最近在做微服务相关产品,其中需要有API网关相关产品,虽然早有研究过API网关产品TYK,但是感觉其太重,想起之前研究开源BI产品saiku的时候,记得其有NodeJS的代理代码,于是看了下,颇有启发,略微修改了一些,拿出来跟大家分享下,虽然简单,不可用于生产,但是对于学习还是不错的

package.json

  1. {
  2. "name": "SmartHttpProxy",
  3. "description": "An simplest Http Proxy",
  4. "version": "0.0.1",
  5. "author": "liuyg@liuyingguang.cn",
  6. "license": {
  7. "type": "Apache License Version 2"
  8. },
  9. "main": "server.js",
  10. "scripts": {
  11. "start": "node server.js 8088 127.0.0.1 80 / "
  12. },
  13. "dependencies": {
  14. "express": "~4.13.4"
  15. }
  16. }

server.js

  1. /*
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. /**
  16. *
  17. * To play with the chaos monkey, set the CHAOS_MONKEY environment variable
  18. * to anything (Preferably a nice name for your chaos monkey).
  19. *
  20. * To start the server, run `node server.js [port] [backend_host] [backend_port]`
  21. */
  22. // newer versions of node.js use the lower-case argv
  23. var argv = process.ARGV || process.argv;
  24. var http = require('http');
  25. var express = require('express');
  26. var path = require('path');
  27. var app = express();
  28. //服务启动端口
  29. var port = process.env.C9_PORT || parseInt(argv[2], 10) || 8088;
  30. //要代理的URL的域名
  31. var backend_host = argv[3] || 'httpbin.org';
  32. //要代理的URL的访问端口
  33. var backend_port = argv[4] || 80;
  34. //要代理的URL的路径
  35. var backend_path_prefix = argv[5] || '/';
  36. //要代理的URL的认证信息
  37. var auth = argv[6] || null;
  38. //拦截替换的路径信息,eg. 如果访问路径为:http://localhost:8088/test/ip,此值设置为“/test/”,则会将其处理为:http://{domain}:{port}/{backend_path_prefix}/ip
  39. //即将path中的第一个与standard_prefix匹配的字符串替换为standard_prefix,如上例子中,处理的结果为:http://httpbin.org/ip
  40. var standard_prefix = "/test/";
  41. // Proxy request
  42. function get_from_proxy(request, response) {
  43. // if a path prefix is set, remove the existing one
  44. if (backend_path_prefix !== '') {
  45. if (request.url.indexOf(standard_prefix) === 0) {
  46. request.url = backend_path_prefix + request.url.substr(standard_prefix.length);
  47. }
  48. }
  49. if (auth) {
  50. request.headers['authorization'] = 'Basic ' + new Buffer(auth).toString('base64');
  51. request.headers['www-authorization'] = 'Basic ' + new Buffer(auth).toString('base64');
  52. delete request.headers['cookie'];
  53. }
  54. var options = {
  55. hostname : backend_host,
  56. port : backend_port,
  57. path : request.url,
  58. method : request.method,
  59. headers : request.headers
  60. };
  61. console.log(options.method, options.path);
  62. var proxy_request = http.request(options);
  63. request.addListener('data', function(chunk) {
  64. proxy_request.write(chunk, 'binary');
  65. });
  66. request.addListener('end', function() {
  67. proxy_request.end();
  68. });
  69. proxy_request.addListener('error', function (error) {
  70. console.log("ERROR:",error);
  71. });
  72. proxy_request.addListener('response', function (proxy_response) {
  73. proxy_response.addListener('data', function(chunk) {
  74. response.write(chunk, 'binary');
  75. });
  76. proxy_response.addListener('end', function() {
  77. response.end();
  78. });
  79. response.writeHead(proxy_response.statusCode, proxy_response.headers);
  80. });
  81. }
  82. // Handle incoming requests
  83. //需要监听访问路径,即只有此路径下的访问,才会被代理
  84. app.all("/test/*", function(request, response) {
  85. request.headers.host = backend_host;
  86. get_from_proxy(request, response);
  87. });
  88. console.log("Connected to '", backend_host, ":", backend_port,"'");
  89. console.log("Proxy listening on", port);
  90. app.listen(port, '0.0.0.0');

by 刘迎光@萤火虫工作室
OpenBI交流群:495266201
MicroService 微服务交流群:217722918
mail: liuyg#liuyingguang.cn
博主首页(==防止爬虫==):http://blog.liuyingguang.cn

Pre: 构建属于自己的elasticsearch Docker镜像

Next: eclipse安装nodejs插件nodeclipse


Table of content