Skip to content

Instantly share code, notes, and snippets.

@leapar
Last active September 30, 2016 08:38
Show Gist options
  • Save leapar/2832bb6b4ac78e4923458199612c592a to your computer and use it in GitHub Desktop.
Save leapar/2832bb6b4ac78e4923458199612c592a to your computer and use it in GitHub Desktop.
macosx kong postgres

#MAC OSX INSTALL KONG 微服务、GO一定能火、NODEJS 大势所趋,日积月累莫后悔

#安装postgres

brew install postgres
initdb /usr/local/var/postgres
/usr/local/Cellar/postgresql/<version>/bin/createuser -s postgres

##修改配置 修改服务端/usr/local/var/postgres/postgresql.conf文件,将

listen_address='localhost'改成  
listen_address='*'

修改/usr/local/var/postgres/gp_hba.conf文件,在文件后面追加:32是掩码

host    all         all         172.29.225.148/32          trust

##启动postgres pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start

然后用navicat连接: 在命令行界面执行CREATE USER kong; CREATE DATABASE kong OWNER kong;

以上postgres 已经ok。

#安装kong

brew install kong

##修改配置 修改/ect/kong/kong.conf把database修改成postgres

##运行 kong start --vv 就ok了。

有个问题,Cassandra一直连不上,报running datastore migrations 然后就出错。 stop service。

Image of Yaktocat

#todo

  1. cassandra 配置
brew search cassandra  
brew install homebrew/***/cassandra22  
不好维护,直接用postgres 放弃
不支持Cassandra 3
  1. kong dashboard 配置
  2. lua插件开发
  3. rmq集成
  4. nginx集成
  5. consul集成
  6. tcp集成

#细节说明

##preserve_host http://172.29.225.161:8000/api/v1/user/login 实际http://172.29.225.148:82/api/v1/user/login ###true:

GET /api/v1/user/login HTTP/1.0
X-Real-IP: 172.29.225.148
X-Forwarded-For: 172.29.225.148
X-Forwarded-Proto: http
Host: 172.29.225.161:8000

###默认false

GET /api/v1/user/regist HTTP/1.0
X-Real-IP: 172.29.225.148
X-Forwarded-For: 172.29.225.148
X-Forwarded-Proto: http
Host: 172.29.225.148:82

##strip_request_path 请求http://172.29.225.161:8000/api/v1/user/login 实际http://172.29.225.148:82/api/v1/user/login ###默认false http://172.29.225.148:82/api/v1/user/login/api/v1/user/login ###true http://172.29.225.148:82/api/v1/user/login 所以strip_request_path 跟upstream_url要配合好,如果upstream_url有path那么strip_request_path设置成true

#api consumer plugin 关系,这是核心 Image of Yaktocat

##表结构:

CREATE TABLE "public"."acls" (
"id" uuid NOT NULL,
"consumer_id" uuid,
"group" text COLLATE "default",
"created_at" timestamp(6) DEFAULT timezone('utc'::text, ('now'::text)::timestamp(0) with time zone)
)
CREATE TABLE "public"."apis" (
"id" uuid NOT NULL,
"name" text COLLATE "default",
"request_host" text COLLATE "default",
"request_path" text COLLATE "default",
"strip_request_path" bool NOT NULL,
"upstream_url" text COLLATE "default",
"preserve_host" bool NOT NULL,
"created_at" timestamp(6) DEFAULT timezone('utc'::text, ('now'::text)::timestamp(0) with time zone)
)
CREATE TABLE "public"."consumers" (
"id" uuid NOT NULL,
"custom_id" text COLLATE "default",
"username" text COLLATE "default",
"created_at" timestamp(6) DEFAULT timezone('utc'::text, ('now'::text)::timestamp(0) with time zone)
)
CREATE TABLE "public"."keyauth_credentials" (
"id" uuid NOT NULL,
"consumer_id" uuid,
"key" text COLLATE "default",
"created_at" timestamp(6) DEFAULT timezone('utc'::text, ('now'::text)::timestamp(0) with time zone)
)
CREATE TABLE "public"."plugins" (
"id" uuid NOT NULL,
"name" text COLLATE "default" NOT NULL,
"api_id" uuid,
"consumer_id" uuid,
"config" json NOT NULL,
"enabled" bool NOT NULL,
"created_at" timestamp(6) DEFAULT timezone('utc'::text, ('now'::text)::timestamp(0) with time zone)
)

##api API是核心,调度核心。根据您的配置,然后当你访问kong服务器kongserver.com/path它会进行调度给upstream就是实际地址: realserver.com/path。并附加一些信息在http头信息中:

GET /api/v1/user/login?keyname=121212 HTTP/1.0
X-Real-IP: 172.29.225.148
X-Forwarded-For: 172.29.225.148
X-Forwarded-Proto: http
Host: 172.29.225.161:8000
Connection: close
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6
Cookie: XSRF-TOKEN=eyJpdiI6Imc4VW44SURJZDlOVkk0bklEODM5K1E9PSIsInZhbHVlIjoid3BMT3MxY1pZSHRDaU9CN1MxNTdTXC9vMk1kNjA2aVRvMmFSZEM4S2xmbkFHMGlJTjFuVm52NXhkNTlKd3hQTUpxOHV2MDBvaVptd29uclVXanF1dzd3PT0iLCJtYWMiOiIzZjU3NDlhYWQyZDZhN2I0NDdhNjc2MzBjMjk1NTAxMzk4MTljNjE2NGJlYjc4NWFkODNhY2ExMDMyODliZjAwIn0%3D; laravel_session=eyJpdiI6InFwaU9WSzluYkdEbjhzVWtGejU1eEE9PSIsInZhbHVlIjoid3E4czQzOWFib2JscjB0RXkzVzc2OTBcL2VxczVaanh5ckxaTGZZSEtlOFRXK1B5cFAxMVprOXg2Y3dcL1B2NkJGajhDRFM2RnE0RURtK1pUQ29Wd1NrZz09IiwibWFjIjoiNDJlOWZhMjA3NTgxMDYyM2QxN2ZkMjYzNDExNjcwNjEwZTdkNThmZjUzYjZiMWE2MzQyOTljNjQyZjM1NTE0OSJ9
X-Consumer-ID: 0d16ea58-561a-46d1-ba39-995f6a231013
X-Consumer-Custom-ID: 1
X-Consumer-Username: 1354509705*

上面的key=121212可以通过配置key-auth插件选项hide_credentials进行关闭,不传递给upstream,默认是会传递的。

##plugins plugins表记录了所有插件的关联以及配置信息,例如某个api绑定了acl,acl的黑白名单都会记录在plugins表中。 记录api、consumer、plugin之间的绑定关系,还记录每个plugin的配置信息。

##consumer consumer可以理解为user,就是用户信息配置。主要两个字段username,custom_id,username唯一的用户,custom_id是自定义的一个id,你可以把它设置成您内部数据库对应的user_id。当kong进行调度时候,会把信息一并带入http header中。

X-Consumer-ID: 0d16ea58-561a-46d1-ba39-995f6a231013
X-Consumer-Custom-ID: 1
X-Consumer-Username: 1354509705*

##keyauth_credentials 由于目前我设计的都是通过token来进行api权限验证,所以这里也采用keyauth。keyauth_credentials表记录的就是每个用户对用的key,他里面两个字段一个是consumer_id一个是key。当你访问时候, http://172.29.225.161:8000/api/v1/user/login?keyname=121212 其中keyname就是配置key-auth时候填写的keyname。121212就是为某个consumer配置的key,kong自动根据请求中的key去查找是哪个用户consumer,然后进行调度,查询不到就会报错。

{
message: "Invalid authentication credentials"
}

##数据扭转 整个系统的核心

  1. 请求数据http://172.29.225.161:8000/api/v1/user/login?keyname=121212
  2. kong根据请求的path跟header里面定义的host到api表查找对应的api
  3. 到plugins查询该api绑定的插件plugin
  4. 进行各个plugin验证,例如发现绑定了key-auth,那么到keyauth_credentials查找key对应的consumer
  5. 把consumer里面绑定的custom id 跟username合并到header中
  6. 调度upstream

#简易实战 先把系统进行切分,拆解。例如一个用户验证微服务,一个订单微服务,一个商品微服务。

  1. 用户请求login,调度到用户认证微服务,登录成功以后,该微服务创建key-auth
  2. 查询商品,根据上一步返回的key查询商品,调度到商品微服务。如果key 或者acl有问题,查询失败。
  3. 调用订单微服务下单
  4. 全部采用rmq进行事件驱动,分布式事务采用最终一致性保证,简化系统设计,银行也是最终一致性。tcc 2pc 3pc那种太复杂。

#进阶 自己开发kong插件。 暂时告一段落,搞段时间python跟go

#kong集群解释 ##原理 kong其实就是基于nginx的反向代理,当访问量很大时候,kong的性能就会有问题,要解决问题就必须采用集群。 每个kong节点之间都会进行通信,所有kong节点都连接到同一个数据库。每次请求,都需要根据api path去匹配插件以及consumer,如果每次都查询数据库,那设计者就是傻逼。所以,每个节点都把数据库中的数据尽量多的缓存在内存中,当数据库数据发生变化时候,重新从数据库中加载数据。这就要求每个kong节点都应该知道有哪些集群节点,当用户从一个kong几点增加consumer、api、或者插件时候,这个节点必须通知其他节点进行数据刷新,否则就会造成内存与数据库中数据不一致。 ##节点加入集群 当第一个kong节点启动,它就必须把自己的ip地址等信息写入数据库,如果是自动获取本地ip失败,那么必须设置cluster_advertise告诉其他节点你的ip地址。后面启动的节点会读取数据库中的节点信息,加入集群。 ##节点退出集群 当kong stop kong quit都会让节点退出集群

##边界问题 当多个节点同一时间启动,那么这时候数据库中还没有集群节点数据,所以采用了一个每3s扫描一次数据库,持续60s的机制。 当某个新节点加入,或者重新加入集群,这时候都会导致集群性能问题,因为每个节点这时候都必须进行数据库数据同步,为了保证内存与数据库数据的一致性。一般情况下可以无视。

@不作声

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment