接口注册程序

接口注册程序读取 $JUSTEP_HOME/model/service 下所有目录中的 app.m(定义平台中的接口),把它们注册到网关中

Kong 中的几个概念

  • service
    • 服务,由服务确定上游的访问地址
  • route
    • 路由,由路由确定使用哪个服务,从而确定上游访问地址
  • plugin
    • 插件,加在服务或路由上的插件,当访问到指定的服务或路由时,插件会被执行
    • 在平台中,插件被限制只能加到路由上
  • upstream
    • 上游,service 通过 hostname 与上游的 name 匹配,用于多目标的负载均衡
  • target
    • 上游的地址,每个地址可以指定不同的权重,用于负载均衡的计算
  • customer
    • 用户,用于权限验证,指定在 plugin 中

app.m 中的几个概念

app.m 根据它的内容,分为静态和动态两种

  • 静态 app.m 是指它的内容是固定的,不需要上下文去计算
    • 一个 app.m 只生成一个对象
  • 动态 app.m 是指它内容需要计算得到
    • 一个 app.m 可能会生成多个对象
    • service 节点上有 loop、when 等发生
    • 下面的 app.m 示例中的第一个 app.m 就是一个动态的 app.m

app.m 示例

<?xml version="1.0" encoding="UTF-8" ?>
<service order="100" target="kong2" tags="registerServices" loop="{{@getRegisteredServices()@}}">
    <name>{{@getItemData(serviceName)@}}</name>
    <request_path>/{{@getItemData(serviceName)@}}</request_path>
    <preserve_host>false</preserve_host>
    <strip_request_path>true</strip_request_path>
    <upstream_url>{{@getItemServiceUrl(serviceName)@}}</upstream_url>

    <plugin name="authentication" enabled="true">
        <app_key>{{.Env.API_KEY}}</app_key>
        <app_secret>{{.Env.API_SECRET}}</app_secret>
        <expire>600</expire>
        <admin_users>system</admin_users>
        <silent_mode>true</silent_mode>
        <auto_refresh_session>true</auto_refresh_session>
    </plugin>

</service>
<?xml version="1.0" encoding="UTF-8" ?>
<upstream>
    <name>aaa-vip.xcaas.com</name>
    <target weight="200">192.168.0.11:8098</target>
    <target weight="100">192.168.0.12:8098</target>
</upstream>
<?xml version="1.0" encoding="UTF-8" ?>
<consumer>
    <name>consumer1</name>
</consumer>

app.m 中根节点有三种类型

  • service
    • 用于定义服务和插件
  • upstream
    • 用于定义上游
  • consumer
    • 用于定义用户

service节点上的属性

  • target
    • 指明接口注册到哪个网关上,它的值只有两个:kong, kong2
      • 只有门户(entry)服务上有 kong2
    • 如果未指定,缺省值是 kong
  • order
    • app.m 被注册的顺序,数值小的先注册
    • 名字相同的接口会被后注册的覆盖
  • loop
    • 值是一个 JSONArray,JSONArray 中的每个 JSONObject 会被注册成一个对象
  • when
    • 值是一个布尔值,使用 when 指定的函数,对平台中所有的 app.m 进行计算,如果结果为真,则用它的内容注册一个对象
  • enabled
    • 值是一个布尔值,如果计算结果是假,则忽略它
  • renew
    • 值是一个布尔值,如果计算结果是真,先删除前面注册的插件,再添加这里定义的插件
  • request_path
    • 定义请求路径,可以是一个字符串,也可以是一个正则表达式;可以有多个值,多个值之间用逗号分隔
    • 示例:/druid,~/[0-9]+.[0-9]+.[0-9]+.[0-9]+/druid
      • /druid, /192.168.0.11/druid 的请求都会匹配到
  • preserve_host
    • 请求到上游时,是否保留主机名
  • strip_request_path
    • 生成上游的请求地址是,是否将 request_path 的值去除
  • upstream_url
    • 请求的上游地址
  • plugin
    • 定义一个插件,名字在节点 name 属性指定
    • 插件的内容根据不同的插件是不同的,需要查看插件的 schema
  • strip_request_path 含义示例
request_path: /myPath
upstream_url: http://192.168.0.11:8080

请求:/myPath/abcd
当 strip_request_path=true 时,到上游的请求为:http://192.168.0.11:8080/abcd
当 strip_request_path=false 时,到上游的请求为:http://192.168.0.11:8080/myPath/abcd

app.m 中的环境变量与函数

在 app.m 中,可以使用服务中定义的环境变量,它的表达方式是:{{.Env.XXXX}};其中 XXXX 是环境变量的名字。 app.m 中也可以使用函数,它的表达方式是:{{@XXXX(YYYY)@}};其中 XXXX 是函数的名字,YYYY 是参数的值。函数可以没有参数。 不管是环境变量还是函数,都不支持嵌套

app.m 中可用的函数列表

  • JSONArray getExternalServices()
    • 返回租户中服务类型(manager_service 表中的 type 字段)为 external 的所有服务
  • String getServiceDomainName(serviceName)
    • 返回租户中服务的内网域名
  • String getItemServiceUrl(key, defaultValue)
    • 返回循环对象中 key 所指向的服务的地址
    • 如果循环对象中没有 key 的值,返回 defaultValue
    • defaultValue 参数可选
  • String getItemData(key, defaultValue)
    • 返回循环对象中 key 的值
    • 如果循环对象中没有 key 的值,返回 defaultValue
    • defaultValue 参数可选
  • String getMetaData(key, defaultValue)
    • 返回 app.m 所在目录的服务的 meta 文件中 key 的值
    • 如果循环对象中没有 key 的值,返回 defaultValue
    • defaultValue 参数可选
  • String hasMetaData(key)
    • 返回 app.m 所在目录的服务的 meta 文件中是否存在 key 的值
  • String getServiceName()
    • app.m 所在目录的名字的最后一段
    • 如:/usr/local/x5/model/service/comp/xxx,返回 xxx
  • String getServiceNameFromPath()
    • 根据 app.m 所在目录的名字的返回服务的目录名
    • 如:/usr/local/x5/model/service/comp/xxx,返回 comp_xxx
  • String getServicePath()
    • 根据 app.m 所在目录的名字的返回服务的目录名
    • 如:/usr/local/x5/model/service/comp/xxx,返回 /comp/xxx
  • String getServicePath2()
    • 根据 app.m 所在目录的名字的返回服务的目录名
    • 如:/usr/local/x5/model/service/comp/xxx,返回 comp/xxx
  • String isMain()
    • 是否是 main 服务
    • 在 /usr/local/x5/model/service/main 下的服务返回 true,其它返回 false
  • String hasDataTable()
    • app.m 所在的服务下面是否有 xxx.data.m 数据集定义
  • String hasTag(tag)
    • 服务上是否有指定的标签
  • String getApiName()
    • API 名字
  • String getApiHosts()
    • API 域名
  • String getApiRequestPath()
    • API 请求路径
  • String getApiServiceAddress()
    • 服务的 XXX_SERVICEADDRESS 环境变量的值
  • String getApiServicePort()
    • 服务的 XXX_PORT 环境变量的值
  • String getApiUpstreamUrl()
    • API 的上游地址
  • String getApiStripRequestPath()
    • API 的 strip_request_path 的值
  • String getApiPreserveHost()
    • API 的 preserve_host 的值
  • String hasApp(appName)
    • 租户中是否有指定的服务
  • String serviceExists(serviceName)
    • 在注册的服务中是否有指定的服务
  • String getRegisteredServices()
    • 返回注册的服务
  • String getRegisteredServicesForRegExp()
    • 返回注册的服务网关匹配字符串,如:[(entry)(wf)]
  • String getTenantCode()
    • 返回租户名
  • String isTenantApp()
    • 服务是否是一个租户服务
  • String getSubServices()
    • 返回租户中的由门户代理的子服务
  • String getContextServiceName()
    • 返回当前服务
  • String isDefined(env, defaultValue)
    • 环境变量是否定义
    • 如果未定义,返回 defaultValue
    • defaultValue 参数可选
  • String isNotDefined(env, defaultValue)
    • 环境变量是否未定义
    • 如果未定义,返回 defaultValue
    • defaultValue 参数可选
  • String isFalseOrNotDefined(env)
    • 环境变量未定义或者值是 false
  • String isBlank(env)
    • 环境变量值是否为空
  • String isNotBlank(env)
    • 环境变量值是否不为空

注册程序执行过程

  • 找出 $JUSTEP_HOME/mode/service 下所有的 app.m
  • 注册静态 app.m
  • 注册动态 app.m
  • 注册只有 plugin 的 app.m
  • 如果网关是 off 模式使用新生成的 yml 文件重新加载配置,如果加载成功,将新生成的文件保存到备份目录,如果加载失败,使用之前成功的配置再次加载
    • off 模式下文件的备份目录
      • 开发时:/storage/data/gateway/dev/kong.yml
      • 运行时:/storage/data/gateway/prod/kong.yml, /storage/data/gateway/prod/kong2.yml(只有 entry 有)

用户自己写 app.m 注意事项

  • app.m 的存放目录
    • 可以自己创建的目录
    • 目录下必须要有 deploy 的信息,可参考 health-check 目录
    • 如果放在一个已有的目录,注意目录中的 .meta 文件中是否有 health-check 的描述,如果有,会自动给接口加上 health-check 插件
  • 如果用户想覆盖掉平台中一个已经有的接口
    • 写一个接口名字相同的 app.m
    • 把 order 设置一个比已经有的接口的 order 更大的值
    • order 的缺省值是 0
  • 如果要给一个接口加插件,首先查看平台的“应用/服务管理”的“更多-网关”功能中,是否已经有此插件,如果有,则从这个功能配置
    • 注意这里加的插件是加在 kong2 上的
    • 如果要加在 kong 上面,现在只支持写 app.m 的方法

results matching ""

    No results matching ""