Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
ffay committed May 7, 2016
1 parent 3a1f161 commit 969f255
Show file tree
Hide file tree
Showing 331 changed files with 35,179 additions and 1 deletion.
Empty file modified LICENSE
100644 → 100755
Empty file.
156 changes: 155 additions & 1 deletion README.md
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1 +1,155 @@
#proxygateway

**PGW(Proxy Gateway)**

Proxy Gateway基于openresty(nginx lua module)开发,通过web配置界面,能够轻松进行代理配置管理,支持负载均衡,服务器状态检测,后续简称PGW。包括以下特性

- 支持多域名,可以配置多个出口域名,互不干扰
- 代理分组(服务模块),可以按照业务模块进行分组
- 负载均衡,可以给每组(每个业务模块)代理配置多台后端服务器,PGW会自动进行负载均衡
- 服务器监控,将down掉的服务器自动剔除,恢复以后自动加入
- 路径配置支持正则表达式对uri进行重写,例如 /user/([0-9]+)/profile /user/profile/$1,所有访问/user/用户id/profile 都将被映射到 /user/profile/用户id
- 集群部署,PGW配置的MySQL数据库使用同一个就能达到集群效果,在任意一台PGW服务器上进行的配置都将在所有PGW服务器上生效
- https配置,与nginx配置一致,修改nginx.conf文件
- 高效,反向代理能力基本和原生nginx一致

**安装**

- 安装最新版本的openresty http:https://openresty.org/en/installation.html
- nginx.conf配置如下,如果按照默认路径(/usr/local/openresty/)安装,可以参考以下步骤

```shell
cd /usr/local/openresty/nginx
git clone https://git.oschina.net/fengfei/proxygateway.git
```

然后把/usr/local/openresty/nginx/conf/nginx.conf 用源码中的nginx.conf替换即可


```
worker_processes 2;
events {
worker_connections 102400;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
lua_shared_dict cache 10m;
#换成你的实际路径,这里将源码中src目录加入到 lua_package_path
lua_package_path '/usr/local/openresty/nginx/proxygateway/src/?.lua;;';
#lua_code_cache off;
upstream servers {
server 127.0.0.1;
balancer_by_lua_block{
local balancer = require "balancer"
balancer.balancing()
}
}
init_worker_by_lua_block{
require "init"
}
server {
listen 80 default_server;
server_name localhost;
location / {
set $backend_host '127.0.0.1';
set $backend_port 80;
set $newhost '';
set $upstream 'http:https://servers';
access_by_lua_block{
local access = require "access"
access.dispatch()
}
proxy_set_header Host $newhost;
proxy_http_version 1.1;
proxy_pass $upstream;
}
error_log logs/error.log;
}
#将源码中的 manage.conf 路径
include /usr/local/openresty/nginx/proxygateway/manage.conf;
}
```

- 配置manage.conf

```
server {
listen 8081;
server_name localhost;
index index.html;
location /api/v1 {
access_by_lua_block{
local access = require "manage.access"
access.checkLogin()
}
content_by_lua_block{
local ctl = require "manage.controller"
ctl.run()
}
}
location /static {
#源码中html的实际路径
root /usr/local/openresty/nginx/proxygateway/html;
}
location / {
access_by_lua_block{
local access = require "manage.access"
access.checkLogin()
}
#源码中html的实际路径
root /usr/local/openresty/nginx/proxygateway/html;
}
}
```

- 在PGW源码中 src/config.lua 进行管理员以及MySQL相关配置
- 在数据库中运行pgw.sql脚本
- 启动openresty(openresty安装目录/nginx/sbin/nginx)
- 在浏览器中打开 http:https://PGW的IP:8081 ,如果是集群部署,打开任意一台的PGW管理界面进行配置即可,登录即可进行域名以及分组代理等配置管理,其中添加的域名需要解析到相应PGW的ip,如果前端还有负载均衡器(例如aws或aliyun的load balancing),域名直接解析到负载均衡器ip即可

**管理配置**
- 域(域名)管理,可以任意添加多个域名,默认域 localhost 在该域下的配置,直接访问IP生效,PGW通过域名进行配置隔离,每个域名下的配置互不干扰,需要将域名解析到PGW的IP
- 服务模块,每个域名下面可以添加多个服务模块,用于将接口按业务模块进行分组
- 后端服务器,每个服务模块下面可以配置多台后端服务器,可以为每台服务器指定权重,负载均衡时会按权重进行接口请求分发,支持http以及https代理
- 代理路径(uri)配置,每个服务模块下可配置多个代理uri规则,配置规则类似nginx location的配置,配置实例

|Request uri|Original uri|说明|
|:---- |:---|:----- |
|/ |/ |将所有对PGW某个域下的请求转发到后端服务器 |
|/u |/user |将所有对PGW某个域下/u开头的请求重写成/user后转发到后端服务器,例如,请求 /u/1001 转发到后端服务器为 /user/1001 |
|/topic/([0-9]+)/([0-9]+) |/topic?uid=$1&tid=$2 |支持正则匹配,请求 /topic/1001/2002 转发到后端服务器为 /topic?uid=1001&tid=2002 |
|/t%?tid=(.*) |/topic?tid=$1 |支持正则匹配,Request uri中如果有 ? 出现,需要在前面加上 % |

所有接口映射配置必须以 / 开头,同一个域下面 Request uri 不能重复,Request uri字符串越长匹配优先级越高

**演示地址**

http:https://a.fengfei.org/
用户名/密码 admin/admin

添加域名后,请将域名cname解析到 a.fengfei.org
然后可在你添加的域名下做代理配置

其中配置的一个google代理,欢迎测试
http:https://google.fengfei.org/

**后续**

- 认证检测
- 访问频率控制
- IP黑白名单
- 数据统计
137 changes: 137 additions & 0 deletions html/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>PROXY-GATEWAY CENTER</title>
<!-- Tell the browser to be responsive to screen width -->
<meta
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
name="viewport">
<!-- Bootstrap 3.3.5 -->
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
<!-- Ionicons
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/ionicons.min.css">
-->
<!-- <link rel="stylesheet" href="/static/font-awesome/css/font-awesome.min.css"> -->
<!-- Theme style -->
<link rel="stylesheet" href="/static/adminlte/css/AdminLTE.min.css">
<!-- AdminLTE Skins. Choose a skin from the css/skins
folder instead of downloading all of them to reduce the load. -->
<link rel="stylesheet"
href="/static/adminlte/css/skins/_all-skins.min.css">

<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:https:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">

<header class="main-header">
<!-- Logo -->
<a href="/" class="logo"> <!-- mini logo for sidebar mini 50x50 pixels -->
<span class="logo-mini"><b>PGW</b></span> <!-- logo for regular state and mobile devices -->
<span class="logo-lg"><b>PROXY GATEWAY</b></span>
</a>
<!-- Header Navbar: style can be found in header.less -->
<nav class="navbar navbar-static-top" role="navigation">
<!-- Sidebar toggle button-->
<a href="#" class="sidebar-toggle" data-toggle="offcanvas"
role="button"> <span class="sr-only"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</a>

<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
<li><a href="/api/v1/logout" class="btn btn-flat">Exit</a></li>
</div>
</nav>
</header>
<!-- Left side column. contains the logo and sidebar -->
<aside class="main-sidebar">
<!-- sidebar: style can be found in sidebar.less -->
<section class="sidebar">
<!-- sidebar menu: : style can be found in sidebar.less -->
<ul class="sidebar-menu">
</ul>
</section>
<!-- /.sidebar -->
</aside>

<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">

<!-- /.content -->
</div>
<!-- /.content-wrapper -->
<footer class="main-footer">
<b>Proxy Gateway Version</b> 0.1
</footer>
</div>
<!-- ./wrapper -->

<!-- jQuery 2.2.0 -->
<script src="/static/plugins/jQuery/jQuery-2.2.0.min.js"></script>
<!-- Bootstrap 3.3.5 -->
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<!-- Slimscroll -->
<script src="/static/plugins/slimScroll/jquery.slimscroll.min.js"></script>
<!-- FastClick -->
<script src="/static/plugins/fastclick/fastclick.js"></script>
<!-- AdminLTE App -->
<script src="/static/adminlte/js/app.min.js"></script>
<!-- AdminLTE for demo purposes -->
<script src="/static/js/main.js"></script>
<script src="/static/js/template.js"></script>
<script id="menu-tpl" type="text/html">
<li class="header">MENU LIST</li>
<li class="treeview active">
<a href="#"><i class="fa fa-folder-o"></i><span>Proxy configuration</span><i class="fa fa-angle-left pull-right"></i></a>
<ul class="treeview-menu">
<%for(var i = 0; i < list.length; i++) {%>
<li><a href="javascript:;" onclick="domain_id=<%:=list[i].id%>;domain_name='<%:=list[i].name%>';load_page('/pages/service/list.html');"><i class="fa fa-circle-o"></i><%:=list[i].name%></a></li>
<%}%>
</ul>
</li>
<li class="treeview">
<a href="#"><i class="fa fa-laptop"></i><span>Domain manage</span><i class="fa fa-angle-left pull-right"></i></a>
<ul class="treeview-menu">
<li><a href="javascript:;" onclick="load_page('/pages/domain/list.html');"><i class="fa fa-circle-o text-aqua"></i><span>Domain list</span></a></li>
<li><a href="javascript:;" onclick="load_page('/pages/domain/add.html');"><i class="fa fa-circle-o text-aqua"></i><span>Add domain</span></a></li>
</ul>
</li>
</script>
<script type="text/javascript">
$(function(){
update_menu(function(domains){
if (domains.length>0) {
domain_id = domains[0].id;
domain_name = domains[0].name;
load_page('/pages/service/list.html');
}
});
});
function update_menu(callback){
api_invoke("/api/v1/domain/all", {}, function(data){
if(data.errno == 0){
var html = template($("#menu-tpl").html(), {list: data.info});
$(".sidebar-menu").html(html);
if (callback) {
callback(data.info);
}
}else{
alert(data.msg);
}
});
}
</script>
</body>
</html>
79 changes: 79 additions & 0 deletions html/login.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Login - Proxy Gateway</title>
<!-- Tell the browser to be responsive to screen width -->
<meta
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
name="viewport">
<!-- Bootstrap 3.3.5 -->
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<!-- Font Awesome
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
-->
<!-- Ionicons
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/ionicons.min.css">
-->
<!-- <link rel="stylesheet" href="/static/font-awesome/css/font-awesome.min.css"> -->
<!-- Theme style -->
<link rel="stylesheet" href="/static/adminlte/css/AdminLTE.min.css">
<!-- AdminLTE Skins. Choose a skin from the css/skins
folder instead of downloading all of them to reduce the load. -->
<link rel="stylesheet"
href="/static/adminlte/css/skins/_all-skins.min.css">

<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:https:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body class="hold-transition skin-blue sidebar-mini">
<div class="login-box">
<div class="login-logo">
<a href="../../index2.html">Proxy Gateway</a>
</div>
<!-- /.login-logo -->
<div class="login-box-body">
<div class="form-group has-feedback">
<input name="username" type="text" class="form-control" placeholder="Username">
<span class="glyphicon glyphicon-user form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input name="password" type="password" class="form-control" placeholder="Password">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block btn-flat">Sign In</button>
</div>
</div>
<!-- /.login-box-body -->
</div>

<!-- jQuery 2.2.0 -->
<script src="/static/plugins/jQuery/jQuery-2.2.0.min.js"></script>
<!-- Bootstrap 3.3.5 -->
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<!-- Slimscroll -->
<script src="/static/plugins/slimScroll/jquery.slimscroll.min.js"></script>
<!-- FastClick -->
<script src="/static/plugins/fastclick/fastclick.js"></script>
<script src="/static/js/main.js"></script>
<script type="text/javascript">
$(".btn").click(function(){
api_invoke("/api/v1/login", {username:$("input[name='username']").val(), password:$("input[name='password']").val()}, function(data){
if(data.errno == 0){
window.location.href="/";
}else{
alert(data.msg);
}
});
});
</script>
</body>
</html>
Loading

0 comments on commit 969f255

Please sign in to comment.