淘先锋技术网

首页 1 2 3 4 5 6 7

主要为了解决SOA服务框架对外提供api相关问题,主要涉及如下几个方面:

  • 统一鉴权
  • 限流
  • 防攻击
  • 系统拆分
  • api横向扩展、高可用、负载均横
  • 服务自动扩缩

为了解决上面的一系列问题,所以需要一个网关系统来作为外部服务调用的统一入口。本方案

分两部分:

第一部分

具体代码请参见 https://github.com/zhuzhong/gateway-dubbox.git

      后端服务采用dubbox的SOA服务框架,服务之间的内部调用协议为dubbo协议,而对于前

端h5提供接口采用的为rest协议,数据传输格式为json,即http+json技术。第一部分主要解决就

是rest协议所提供的服务对外的网关问题。

目的

    我们服务框架使用的是dubbox(这个不用再多描述了),内部系统调用使用的是dubbo协议;

而对于前端提供服务则使用rest协议。前端应用面临许多rest服务,为了解决调用的统一,所

以需要一个网关系统。

为什么自己写

  •        对于api网关,现在已有框架可以解决该类问题,但是基于java语言开源的没有(除了zuul,也有可能我没有找到).
  •        不会C++,无法扩展nginx
  •        不会C,无法扩展nginx
  •        不会LUA,无法扩展nginx

功能设计

       最初根据个人理解构建一个版本https://github.com/zhuzhong/gateway.git,但是版本设计

的太复杂,尤其是前端参数传递,并且网关与后端服务的心跳检测的功能没有,服务的注册

发现都是手动完成,不是自动的。本次设计方案参考spring-cloud的zuul的设计思路。然大部分

代码采用了上一个版本的,但整体的设计思路已经发生转变,可以认为是两个不同的版本,因

为在使用方式上也完全不一样。也可以只参考这一个版本,而不需要关心上一个版本的内容。

主要功能

  •            前端请求的统一拦截;

  •           负载均衡;

  •            心跳检测

  •         鉴权

  •         参数校验

  •         路由

路由规则

      很简单:前端请求的url,去掉网关的contextpath后对应的url地址即为相应后端服务的url 


      对于后端服务的url,分两部:一部分为上下文contextpath;一部分为请求路径;

 
      通过监听注册中心zk,可以获取所有提供rest服务的服务器列表,根据服务的contextpath

进行分组,然后进行路由请求。

后端服务列表获取

      后端服务列表,通过监听注册中心zk,然后解析出相应的服务列表。当注册中心中注入的

服务地址发生变化,则重新再次解析; 


      zk帮我们完成后端服务列表运态变化以及心跳检测;

示例

  1.      前端请求url:http://localhost:8080/gateway/restapi/test

    •          则网关的contextpath=gateway

    •         后端服务的contextpath=restapi

    •        根据后端服务的contextpath=restapi得到一组服务器列表,选其一比如http://localhost:5644/

    •     则后端的服务的完整api服务地址为: http://localhost:5644/restapi/test

    •     然后调用该接口获取相应的响应,返回前端即可

技术栈

  •       springmvc
  •       spring
  •       servlet3异步
  •       httpclient 4.5.3
  •         zookeeper        apache-chain


第二部分

     代码请参见https://github.com/zhuzhong/gateway-ngxcfg.git ,这一部分主要解决网关的自动

扩缩及负载均衡等问题.

目的

        使用nginx作为第一部分网关的反向代理服务器,则该网关系统只能通过手动进行扩缩,无

自动扩缩。为了解决这个问题,可以采用LUA脚本和采用nginx plus,但是这两个要求对于我来

说,都不可行,所以只能自造轮子。该轮子主要是为了解决项目https://github.com/zhuzhong/gatew

ay-dubbox.git的负载均衡及动态扩缩问题。

设计思路

     设计思路主要参考 http://blog.csdn.net/akin_zhou/article/details/50373414

  1.      从注册中心zookeeper拉取相应的服务列表; 


  2.      从注册中心拉取相应的服务列表,主要是为了获取nginx的配置信息需要服务地址及端口相

  3. 应的信息。生成nginx的配置文件; 

  4.    

    •     生成nginx的配置信息,主要分为两部分

    •                   upstream部分

    •                   location部分

    •      这两部分以include的形式引入nginx的主配置文件
  5.     让nginx重新加载新的配置文件

使用示例

  1. gateway-dubbox中启用这个bean,并启动gateway-dubbox服务,使其注入注册中心

    <!-- 虚拟服务注入注册中心 -->
    <bean class="com.aldb.gateway.service.support.DefaultVirtualServiceImpl" init-method="init">
    <property name="rootPath" value="${virtual.zk.rootpath}"></property>
    <property name="zkServers" value="${virtual.zk.zkservers}"></property>
    <property name="context" value="${proj.contextPath}"></property>
    <property name="ip" value="${virtual.ip}"></property>
    <property name="port" value="${virtual.port}"></property>
    
    

  2. 配置nginx.conf

           在http部分增加 include /opt/test/up.conf; 


  3.        在server部分增加 include /opt/test/lo.conf;

  4. 配置gateway-ngxcfg

           使用与gateway-dubbox的虚拟服务相同的注册中心

  5.        启动gateway-ngxcfg,该服务与nginx部署同一机器

          查看是否已经在相应的目录中生成相应的配置文件,并注意观察一下nginx的master 

  6. process id 是否变化了。nginx重新reload配置文件,是通过java调用shell来完成,而相应

  7. 的shell文件需要放在服务器上(可参见源码中的shell-demo.sh),并配置相应的shellFile参数