|
1 | 1 | ## 路由配置 |
2 | 2 | 路由配置表示了camellia-redis-proxy在收到客户端的redis命令之后的转发规则 |
3 | 3 |
|
4 | | -## 大纲 |
5 | | -* 最简单的示例 |
6 | | -* 支持的后端redis类型 |
7 | | -* 动态配置和复杂配置(读写分离、分片等) |
8 | | -* 多租户支持 |
9 | | -* 使用camellia-dashboard管理多租户动态路由 |
10 | | -* 集成ProxyRouteConfUpdater自定义管理多租户动态路由 |
11 | | - |
12 | 4 | ### 最简单的示例 |
13 | | -在application.yml里配置如下信息: |
14 | | -```yaml |
15 | | -server: |
16 | | - port: 6380 |
17 | | -spring: |
18 | | - application: |
19 | | - name: camellia-redis-proxy-server |
20 | | - |
21 | | -camellia-redis-proxy: |
22 | | - password: pass123 |
23 | | - transpond: |
24 | | - type: local |
25 | | - local: |
26 | | - type: simple |
27 | | - resource: redis-cluster://@127.0.0.1:6379,127.0.0.1:6378,127.0.0.1:6377 |
| 5 | +在`camellia-redis-proxy.properties` |
| 6 | +```properties |
| 7 | +port=6380 |
| 8 | +password=pass123 |
| 9 | +route.conf=redis-cluster://@127.0.0.1:6379,127.0.0.1:6378,127.0.0.1:6377 |
28 | 10 | ``` |
29 | 11 | 上面的配置表示proxy的端口=6380,proxy的密码=pass123,代理到后端redis-cluster集群,地址串=127.0.0.1:6379,127.0.0.1:6378,127.0.0.1:6377 |
30 | 12 |
|
31 | 13 | ### 支持的后端redis类型 |
32 | | -具体见:[redis-resources](redis-resources.md) |
33 | | -
|
34 | | -### 动态配置(单租户) |
35 | | -具体见:[dynamic-conf](dynamic-conf.md) |
| 14 | +* `route.conf` 不仅仅支持redis-cluster,也支持各种类型的redis后端 |
| 15 | +* 具体见:[redis-resources](redis-resources.md) |
36 | 16 |
|
37 | 17 | ### 如何定义一个复杂配置(读写分离、分片等) |
38 | | -具体见:[complex](complex.md) |
| 18 | +* `route.conf` 不仅仅可以配置一个地址串,也可以配置一个json,来描述读写分离、分片等复杂逻辑 |
| 19 | +* 具体见:[complex](complex.md) |
| 20 | + |
| 21 | +### 底层逻辑 |
| 22 | +* 上面的最简单的示例中只有3行配置,但是通过更多的配置,你可以实现以下效果 |
| 23 | +* 多租户支持,也就是逻辑上支持配置多个 `route.conf` ,类似于nginx不同的server |
| 24 | +* 那proxy如何判断应该走哪个 `route.conf` 呢?有两种方法,一种是建立连接时调用 `client setname` 命令来告诉proxy,一个是通过不同的 `password` 来告诉proxy |
| 25 | +* 通过 `password` 选择路由的建议和最初实现来自于 [@yangxb2010000](https://github.com/yangxb2010000) |
| 26 | + |
| 27 | +### proxy的路由功能包括2个环节 |
| 28 | +* 一个是建立连接时选定路由,在proxy中,一个路由我们通过bid和bgroup两个字段来描述,前者为一个数字,后者为一个字符串(为什么是2个字段而不是1个字段,这是历史原因,不要深究) |
| 29 | +* 选定了路由后,proxy再找到bid/bgroup对应的 `route.conf` ,可能是一个redis地址,也可能是一个复杂的json配置 |
| 30 | +* 通过这种两层的逻辑架构,客户端连接不断开的情况下,就可以动态切换后端了 |
| 31 | + |
| 32 | +### 路由选择的实现 |
| 33 | +* 具体见:`RouteConfProvider.java` |
| 34 | +* 这是一个抽象类,有多种内置实现,你也可以自定义,类定义如下: |
| 35 | + |
| 36 | +```java |
| 37 | + public abstract ClientIdentity auth(String userName, String password); |
| 38 | + |
| 39 | + public abstract boolean isPasswordRequired(); |
| 40 | + |
| 41 | + public abstract ResourceTable getRouteConfig(long bid, String bgroup); |
| 42 | + |
| 43 | + public abstract boolean isMultiTenantsSupport(); |
| 44 | + |
| 45 | + public final void invokeUpdateResourceTable(long bid, String bgroup, ResourceTable resourceTable) {} |
| 46 | + public final void invokeRemoveResourceTable(long bid, String bgroup) {} |
| 47 | +``` |
| 48 | + |
| 49 | +* `auth` 和 `isPasswordRequired` 在建立连接时使用,会返回登录成功或者失败 |
| 50 | +* `ClientIdentity` 内部包含了bid和bgroup两个字段,proxy会把相关信息绑定到建立好的客户端连接上 |
| 51 | +* 当客户端连接建立好后,发起redis命令,如 `get` 和 `set`,proxy会取出连接上的bid和bgroup信息,去调用 `getRouteConfig` 方法,获取到路由配置,并做转发 |
| 52 | +* `isMultiTenantsSupport` 用于告诉proxy,当bid和bgroup不同时,ResourceTable是不是会不一样,如果 `isMultiTenantsSupport=true`,则代表有多条路由 |
| 53 | +* `invokeUpdateResourceTable` 和 `invokeRemoveResourceTable` 是两个回调方法,当某个bid和bgroup对应的 `route.conf` 发生了变化,可以通过这两个回调来告诉proxy |
| 54 | +* 正是因为有这两个回调方法的存在,因此并不是每个 `get` 和 `set` 命令都会触发 `getRouteConfig` 方法的调用,proxy会缓存结果以便有更好的性能 |
| 55 | +* 你可以调用 `ResourceTable ReadableResourceTableUtil.parseTable(String routeConf)` 方法,把 `route.conf` 转换为 `ResourceTable` 对象 |
| 56 | + |
| 57 | + |
| 58 | +### 内置的RouteConfProvider实现 |
| 59 | +* 具体见:`RouteConfProviderEnums.java` |
| 60 | +* 当前内置了5种实现,文档开头的最简单配置,实际上使用了 `DefaultRouteConfProvider.java` 这一默认实现 |
39 | 61 |
|
40 | | -### 多租户支持 |
41 | | -具体见:[tenant](tenant.md) |
42 | 62 |
|
43 | | -### 使用camellia-dashboard管理多租户动态路由 |
44 | | -具体见:[dashboard](dashboard.md) |
| 63 | +#### DefaultRouteConfProvider.java |
| 64 | +* 这是默认实现,该实现不支持多租户,也就是 `isMultiTenantsSupport=false` |
| 65 | +```properties |
| 66 | +route.conf.provider=default |
45 | 67 |
|
46 | | -### 使用ProxyRouteConfUpdater自定义管理多租户动态路由 |
47 | | -具体见:[route-conf-updater](route-conf-updater.md) |
| 68 | +#### 优先看route.conf,如果没有则看route.conf.file |
| 69 | +#### 支持单个地址,也支持复杂配置(json) |
| 70 | +route.conf=redis://@127.0.0.1:6379 |
| 71 | +#route.conf={"type": "simple","operation": {"read": "redis://passwd123@127.0.0.1:6379","type": "rw_separate","write": "redis-sentinel://passwd2@127.0.0.1:6379,127.0.0.1:6378/master"}} |
| 72 | +#### 支持外置其他配置文件作为数据原,支持class_path下的文件名,也支持绝对路径下的文件地址 |
| 73 | +route.conf.file=resource-table.json |
| 74 | +#### 配置检查更新的间隔 |
| 75 | +route.conf.check.interval.millis=3000 |
| 76 | +``` |
| 77 | + |
| 78 | +#### CamelliaDashboardRouteConfProvider.java |
| 79 | +* 该实现下,路由配置托管给了 `camellia-dashboard`,支持配置多租户,也可以关掉多租户 |
| 80 | +* 该模式下,客户端登录后,需要使用 `client setname camellia_1_default` 命令告诉服务器,选择了bid=1和bgroup=default这组路由配置 |
| 81 | +* 这种模式内部主要是为了统一管理redis-proxy和其他配置(如camellia-feign、camellia-hbase),如果你单独使用redis-proxy,可以跳过 |
| 82 | +```properties |
| 83 | +route.conf.provider=camellia_dashboard |
| 84 | + |
| 85 | +# |
| 86 | +camellia.dashboard.url=http://127.0.0.1:8080 |
| 87 | +## 当客户端没有告诉服务器bid/bgroup时,默认的bid和bgroup |
| 88 | +camellia.dashboard.bid=1 |
| 89 | +camellia.dashboard.bgroup=default |
| 90 | +## 设置为true,表示支持多租户 |
| 91 | +camellia.dashboard.dynamic=true |
| 92 | +camellia.dashboard.monitor.enable=false |
| 93 | +camellia.dashboard.check.interval.millis=5000 |
| 94 | +camellia.dashboard.connect.timeout.millis=10000 |
| 95 | +camellia.dashboard.read.timeout.millis=60000 |
| 96 | +camellia.dashboard.headers={"k1":"v1"} |
| 97 | +``` |
| 98 | + |
| 99 | +#### MultiTenantsV1RouteConfProvider.java |
| 100 | +* 该实现下,路由配置托管给了本地配置文件,支持多租户 |
| 101 | +* 配置方式更适合properties格式的配置文件 |
| 102 | +```properties |
| 103 | +route.conf.provider=multi_tenants_v1 |
| 104 | + |
| 105 | +#### 表示pass123密码指向bid=1/bgroup=default,路由是redis://@127.0.0.1:6379 |
| 106 | +pass123.password.1.default.route.conf=redis://@127.0.0.1:6379 |
| 107 | +#### 表示pass456密码指向bid=2/bgroup=default,路由是一个复杂的配置 |
| 108 | +pass456.password.2.default.route.conf={"type": "simple","operation": {"read": "redis://passwd123@127.0.0.1:6379","type": "rw_separate","write": "redis-sentinel://passwd2@127.0.0.1:6379,127.0.0.1:6378/master"}} |
| 109 | + |
| 110 | +``` |
| 111 | + |
| 112 | +#### MultiTenantsV2RouteConfProvider.java |
| 113 | +* 该实现下,路由配置托管给了本地配置文件,支持多租户 |
| 114 | +* 配置方式更适合json格式的配置文件 |
| 115 | +```json |
| 116 | +{ |
| 117 | + "route.conf.provider": "multi_tenants_v1", |
| 118 | + "multi.tenant.route.config": |
| 119 | + [ |
| 120 | + { |
| 121 | + "bid": 1, |
| 122 | + "bgroup": "route1", |
| 123 | + "password": "passwd1", |
| 124 | + "route": "redis://passxx@127.0.0.1:16379" |
| 125 | + }, |
| 126 | + { |
| 127 | + "bid": 1, |
| 128 | + "bgroup": "route2", |
| 129 | + "password": "passwd2", |
| 130 | + "route": "redis-cluster://@127.0.0.1:6380,127.0.0.1:6381,127.0.0.1:6382" |
| 131 | + }, |
| 132 | + { |
| 133 | + "bid": 1, |
| 134 | + "bgroup": "route3", |
| 135 | + "password": "passwd3", |
| 136 | + "route": |
| 137 | + { |
| 138 | + "type": "simple", |
| 139 | + "operation": |
| 140 | + { |
| 141 | + "read": "redis://passwd123@127.0.0.1:6379", |
| 142 | + "type": "rw_separate", |
| 143 | + "write": "redis-sentinel://passwd2@127.0.0.1:6379,127.0.0.1:6378/master" |
| 144 | + } |
| 145 | + } |
| 146 | + } |
| 147 | + ] |
| 148 | +} |
| 149 | +``` |
| 150 | + |
| 151 | +#### SimpleConfigRouteConfProvider.java |
| 152 | +* 该实现下,路由配置托管给了外部的simple_config服务,支持多租户 |
| 153 | +* simple_config的接口规范参考 `SimpleConfigFetcher.java` |
| 154 | +```properties |
| 155 | +route.conf.provider=multi_tenants_simple_config |
| 156 | + |
| 157 | +#### 外部系统(满足simple_config的接口规范即可) |
| 158 | +simple.config.fetch.url=http://127.0.0.1:8080 |
| 159 | +simple.config.fetch.key=xxx |
| 160 | +simple.config.fetch.secret=xxx |
| 161 | +#### 表示pass123密码指向bid=1/bgroup=default,路由biz=biz1,路由配置通过外部simple_config系统获取 |
| 162 | +pass123.password.1.default.route.conf.biz=biz1 |
| 163 | +#### 表示pass456密码指向bid=2/bgroup=default,路由biz=biz2,路由配置通过外部simple_config系统获取 |
| 164 | +pass456.password.2.default.route.conf.biz=biz2 |
| 165 | +``` |
48 | 166 |
|
| 167 | +#### 当然你也可以自定义 |
| 168 | +```properties |
| 169 | +# 配置全路径的类名即可 |
| 170 | +route.conf.provider=com.xxx.xxx.CustomRouteConfProvider |
| 171 | +``` |
0 commit comments