Giter Club home page Giter Club logo

camellia's Introduction

camellia(ENGLISH

Camellia是网易云信开发的服务器基础组件,所有模块均已应用于网易云信线上环境

GitHub Maven Central

模块介绍

Camellia提供了一系列简单易用的服务器组件,包括但不限于:

独立部署的中间件服务(server)

更多:

  • 以上中间件默认使用java8/spring-boot2运行,如果要使用java21/spring-boot3,请参考:camellia-jdk21-bootstraps
  • 以上中间件支持使用prometheus/grafana对服务进行监控,请参考:prometheus/grafana

增强的三方库(sdk)

此外,还包括其他众多简单易用的三方库(基于开源版本进行二次增强):

功能简介

camellia-redis-proxy

基于netty4开发的一款高性能redis代理

  • 支持redis-standalone/redis-sentinel/redis-cluster
  • 支持其他proxy作为后端(如双写迁移场景),如 twemproxycodis
  • 支持 kvrockspikatendis 等作为后端
  • 支持普通的GET/SET/EVAL,也支持MGET/MSET,也支持阻塞型的BLPOP,也支持PUBSUB和TRANSACTION,也支持STREAMS/JSON/SEARCH/BloomFilter/CuckooFilter,也支持TAIR_HASH/TAIR_ZSET/TAIR_STRING
  • 支持SCAN命令,即使后端是redis-cluster或者自定义分片,也可以透明的扫描到所有key
  • 支持SELECT命令,从而可以使用多database
  • 所有支持的命令: supported_commands
  • 支持SSL/TLS(client到proxy支持,proxy到redis也支持)
  • 支持unix-domain-socket(client到proxy支持,proxy到redis也支持)
  • 支持使用http协议访问proxy,类似于 webdis ,但是接口定义不一样,具体见:http
  • 支持自定义分片、读写分离、双(多)写、双(多)读
  • 支持多租户(可以同时代理多组路由,可以通过不同的登录密码来区分)
  • 支持多租户动态路由,支持自定义的动态路由数据源(内置:本地配置文件、nacos、etcd等,也可以自定义)
  • 支持读从节点(redis-sentinel、redis-cluster都支持)
  • 高可用,可以基于lb组成集群,也可以基于注册中心组成集群,也可以伪装成redis-cluster组成集群,也可以伪装成redis-sentinel组成集群
  • 支持自定义插件,并且内置了很多插件,可以按需使用(包括:大key监控、热key监控、热key缓存、key命名空间、ip黑白名单、速率控制等等)
  • 支持丰富的监控,如TPS、RT、热key、大key、慢查询、连接数等
  • 支持使用prometheus/grafana来监控proxy集群
  • 支持使用hbase/obkv/tikv等作为底层存储,构建一个类redis的系统,具体见:kv
    快速开始

camellia-id-gen

提供了多种id生成算法,开箱即用,包括:

  • 雪花算法(支持设置单元标记)
  • 严格递增的id生成算法(步长支持动态调整)
  • 趋势递增的id生成算法(支持设置单元标记,支持多单元id同步)
  • 支持使用prometheus/grafana来监控id-gen-server集群
    快速开始

camellia-delay-queue

基于redis实现的延迟队列服务:

  • 独立部署delay-queue-server服务器,支持水平扩展,支持多topic,以http协议对外提供服务(短轮询or长轮询),支持多语言客户端
  • 提供了一个java-sdk,并且支持以spring-boot方式快速接入
  • 支持丰富的监控数据
  • 支持使用prometheus/grafana来监控delay-queue-server集群
    快速开始

camellia-hot-key

热key探测和缓存服务:

  • 支持热key探测,也支持热key缓存,也支持topN统计
  • 支持丰富的自定义扩展口(热key通知、topN通知、热key规则数据源、热key缓存命中统计)
  • 支持自定义数据源(内置:本地配置文件、nacos、etcd,也可以自己实现)
  • 支持自定义注册中心(内置:zk、eureka,也可以自己实现)
  • 支持丰富的监控数据
  • 支持使用prometheus/grafana来监控hot-key-server集群
    快速开始

RELEASE版本

最新版本是1.2.27,已经发布到maven**仓库(2024/03/13)
更新日志

SNAPSHOT版本

当前最新是1.2.28-SNAPSHOT

<repositories>
  <repository>
    <id>sonatype-snapshots</id>
    <name>Sonatype Snapshot Repository</name>
    <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
    <snapshots>
      <enabled>true</enabled>
    </snapshots>
  </repository>
</repositories>

谁在使用Camellia

如果觉得 Camellia 对你有用,欢迎Star/Fork
欢迎所有 Camellia 用户及贡献者在 这里 分享您在当前工作中开发/使用 Camellia 的故事

联系方式

微信: hdnxttl(加此微信拉进技术交流群)
email: [email protected]

Stargazers Over Time

Stargazers Over Time

camellia's People

Contributors

21want28k avatar 48n6e avatar caojiajun avatar chanjarster avatar cvedetect avatar dependabot[bot] avatar dyrnq avatar helloworld1018 avatar inputoutputz avatar nxttl-ucas avatar tain198127 avatar tasszz2k avatar ttiantian006 avatar wozaizhe55 avatar yangxb2010000 avatar zhaoxiaojie0415 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

camellia's Issues

双写是否能保证原子性

我们公司的项目都是发布在两个机房里面,采用的是异地双机房部署,双写功能,能不能做到原子性呢?

性能测试对比的问题

我这儿想使用redis的proxy,就分别对camellia-redis-proxy、bilibili-overlord和predixy进行了性能测试对比

配置和这里介绍的一样
https://github.com/netease-im/camellia/blob/master/camellia-redis-proxy/performance-report-1.md

camellia-redis-proxy用的是async模式,用1.0.5版本编译的。可是性能测试结果和您这儿的结果差距有点大。我这儿测试的camellia-redis-proxy对比bilibili-overlord和predixy差了一个数量级。比如单连接时测试get命令,camellia-redis-proxy的平均响应时间是1.5079,而bilibili-overlord和predixy分别是0.17和0.14

不知是不是我用的版本有问题?还是有什么调优的方式?

redis ssl 支持

camellia-redis-proxy如何配置启用ssl来连接到redis cluster?

双写的问题。

请教一下,这个双写,是两个线程同时向两个主发起写,还是按顺序,一个个发起写入?

配置读写分离的resource-table.json打成jar包通过docker部署时读取不到文件的问题

2021-01-29 03:47:45.763 ERROR 1 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'commandInvoker' defined in class path resource [com/netease/nim/camellia/redis/proxy/springboot/CamelliaRedisProxyConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.netease.nim.camellia.redis.proxy.command.CommandInvoker]: Factory method 'commandInvoker' threw exception; nested exception is java.lang.IllegalArgumentException: not found redis-proxy-0.0.1-SNAPSHOT/BOOT-INF/classes!/resource-table.json

Bug: KeyConverter does not work with the SCAN command

Bug: KeyConverter does not work with the SCAN command

I use CustomKeyConverter implements KeyConverter. It still works with the GET/SET/PUSH/KEY/... commands. But, today, I test with the SCAN command, and it doesn't work the right way. It gets all keys from the Redis resource without the prefix "bid|bgroup" defined


  • My CustomKeyConverter class:
public class CustomKeyConverter implements KeyConverter {
  public static final byte[] SEPARATOR = Utils.stringToBytes("|");

  @Override
  public byte[] convert(
      CommandContext commandContext, RedisCommand redisCommand, byte[] originalKey) {
    if (commandContext.getBid() == null || commandContext.getBgroup() == null) {
      return originalKey;
    }
    byte[] bid = Utils.numToBytes(commandContext.getBid(), false);
    byte[] bgroup = Utils.stringToBytes(commandContext.getBgroup());
    byte[] convertedKey =
        new byte
            [bid.length + SEPARATOR.length + bgroup.length + SEPARATOR.length + originalKey.length];
    System.arraycopy(bid, 0, convertedKey, 0, bid.length);
    System.arraycopy(SEPARATOR, 0, convertedKey, bid.length, SEPARATOR.length);
    System.arraycopy(bgroup, 0, convertedKey, bid.length + SEPARATOR.length, bgroup.length);
    System.arraycopy(
        SEPARATOR,
        0,
        convertedKey,
        bid.length + SEPARATOR.length + bgroup.length,
        SEPARATOR.length);
    System.arraycopy(
        originalKey,
        0,
        convertedKey,
        bid.length + SEPARATOR.length + bgroup.length + SEPARATOR.length,
        originalKey.length);
    return convertedKey;
  }

  @Override
  public byte[] reverseConvert(
      CommandContext commandContext, RedisCommand redisCommand, byte[] convertedKey) {
    if (commandContext.getBid() == null || commandContext.getBgroup() == null) {
      return convertedKey;
    }
    byte[] bid = Utils.numToBytes(commandContext.getBid(), false);
    byte[] bgroup = Utils.stringToBytes(commandContext.getBgroup());
    byte[] originalKey =
        new byte
            [convertedKey.length
                - bid.length
                - SEPARATOR.length
                - bgroup.length
                - SEPARATOR.length];
    System.arraycopy(
        convertedKey,
        bid.length + SEPARATOR.length + bgroup.length + SEPARATOR.length,
        originalKey,
        0,
        originalKey.length);
    return originalKey;
  }
}
  • Test result:
127.0.0.1:6380> mget k1 k2 k3
1) "tass2"
2) "tass2"
3) "tass3"
127.0.0.1:6380> keys *
1) "k5"
2) "k3"
3) "k4"
4) "k2"
5) "k1"
127.0.0.1:6380> scan 0 match k*         #---> Expect: k1,k2,k3,k4,k5...
1) "60"
2) (empty array)
127.0.0.1:6380> scan 0 count 10         #---> Expect: k1,k2,k3,k4,k5...
1) "60"
2)  1) "ev.monitoring.metric.incrchecked.2212061614"
    2) "a_table|1"
    3) "ev.monitoring.metric.incrchecked.2212061615"
    4) "a_stats_|redis://@127.0.0.1:6379|AsyncCamelliaRedisTemplate|mset|W"
    5) "a_stats_|redis://@127.0.0.1:6379|AsyncCamelliaRedisTemplate|scan|R"
    6) "a_stats_|camellia_t_keys"
    7) "a_stats_|redis://[email protected]:6379|AsyncCamelliaRedisTemplate|command|R"
    8) "a_table|2"
    9) "a_stats_|redis://@127.0.0.1:6379|AsyncCamelliaRedisTemplate|exists|R"
   10) "a_stats_|redis://@127.0.0.1:6379|AsyncCamelliaRedisTemplate|incrby|W"
(0.68s)

ReplyEncoder:channel not active

时不时的就会报这个错误
ERROR error-log-collector-pool-7-thread-1 c.n.n.c.r.p.u.ErrorLogCollector:62 - com.netease.nim.camellia.redis.proxy.netty.ReplyEncoder:channel not active, remote.ip=/10.120.5.63:47359, count = 1

我记得重启,刚起动完,就会报一下。然后偶尔就会报一个

连接池配制

这个proxy 配制文件是否配制与后端redis 的连接 池。
类似jedis 的 max_active 或者 max_total 这个最大连接数的配制 ?
2、这个到proxy --> redis 连接 ,我看只有3个网络连接。这个是写死的吗?
谢谢

双写网络故障问题

你好,请问下,双写过程如果某个机房网络故障,双写出现问题这种情况怎么补救,有没有办法让数据做到最终一致性,或者该程序是否已经考虑并解决这个问题了?

Cannot load configuration class: com.netease.nim.camellia.redis.proxy.samples.Application

Hi,
I do everything like that:

wget https://github.com/netease-im/camellia/releases/download/1.1.7/camellia-redis-proxy-1.1.7.tar.gz
tar zxvf camellia-redis-proxy-1.1.7.tar.gz
cd camellia-redis-proxy-1.1.7/
jar -cvf0M camellia-redis-proxy.jar BOOT-INF/ META-INF/ org/
java -XX:+UseG1GC -XX:+UseContainerSupport -Xms2048m -Xmx2048m -server -jar camellia-redis-proxy.jar --spring.config.location=file:application.yml

When last command run I got this error:

2022-12-02 14:50:03,701 ERROR main  o.s.b.SpringApplication:837 - Application run failed
java.lang.IllegalStateException: Cannot load configuration class: com.netease.nim.camellia.redis.proxy.samples.Application

Please help me.

建议优化项目的About

最近也在研究redis proxy的方案,你这个项目的About,说了一句和框架没关系的描述,通过关键字redis proxy,都搜索不到,我建议你优化一下项目的About

RedisMonitor中upstream的耗时会存在比commandSpend还大的可能吗

日志如下

2022-06-16 14:55:44.958 [INFO] [camellia-schedule-1-8] [camellia.redis.proxy.stats] @@@traceid=N/A@@@ ====spend.stats====
2022-06-16 14:55:44.958 [INFO] [camellia-schedule-1-8] [camellia.redis.proxy.stats] @@@traceid=N/A@@@ command=auth,count=2,avgSpendMs=0.005009,maxSpendMs=0
.005018
2022-06-16 14:55:44.958 [INFO] [camellia-schedule-1-8] [camellia.redis.proxy.stats] @@@traceid=N/A@@@ command=publish,count=2,avgSpendMs=1.170809,maxSpendM
s=1.174107
2022-06-16 14:55:44.958 [INFO] [camellia-schedule-1-8] [camellia.redis.proxy.stats] @@@traceid=N/A@@@ command=get,count=4,avgSpendMs=1.05341025,maxSpendMs=
1.065794
2022-06-16 14:55:44.958 [INFO] [camellia-schedule-1-8] [camellia.redis.proxy.stats] @@@traceid=N/A@@@ command=exists,count=4,avgSpendMs=1.12897225,maxSpend
Ms=1.164166
2022-06-16 14:55:44.958 [INFO] [camellia-schedule-1-8] [camellia.redis.proxy.stats] @@@traceid=N/A@@@ command=brpop,count=3,avgSpendMs=1265.753878,maxSpend
Ms=1598.487612

2022-06-16 14:55:44.958 [INFO] [camellia-schedule-1-8] [camellia.redis.proxy.stats] @@@traceid=N/A@@@ ====upstream.redis.spend.stats====
2022-06-16 14:55:44.958 [INFO] [camellia-schedule-1-8] [camellia.redis.proxy.stats] @@@traceid=N/A@@@ [email protected]:6379,count=15,avgSpendMs=4398.119012933334,maxSpendMs=46122.952246

如果代理Redis Cluster,Key路由逻辑是什么?

如果代理Redis Cluster,Key路由逻辑是什么?

  • 和官方一样CRC16,直接把Key路由到正确Slot上
  • 和普通客户端一样,随便路由到某个节点,通过 MOVED/ASK 来重定向到正确Slot上

另外,如果代理Redis Cluster,自定义sharding还能用吗?

请问pipeline模式会丢失命令吗?

目前看是用AsyncTaskQueue类支持了pipeline模式。如果一个pipeline中有10个命令,queue中有10个AsyncTask,调用10次callback方法。

如果连续调用10次callback方法,只有第一次生效,其余九次直接返回,如果第一次writeAndFlush时有网络异常导致走到finally里了,但channelInactive又没有触发,是不是会导致pipeline的10条命令一直留在queue中,直到客户端再次请求?而且客户端再次请求时,回复的是上次pipeline中的命令导致异常。如果客户端一段时间内没有再次请求,上一次的pipeline命令会超时失败。

目前没有试过这种情形,想请问下上面这种说法成不成立?

云信redis代理和官方推出的Redis cluster proxy之间的区别?

您好,现在正在研究云信的redis代理,想咨询一下您以下问题?
1.官方已经推出了Redis 6.0多线程版本,那么云信redis使用netty实现代理的方式,是不是不占优势。
2.官方其实也推出了相关的Redis cluster proxy,那么相比官方的redis cluster proxy云信proxy有什么特别之处?
上面是我的一些问题,只是单纯的想明白云信的优势,然后选择使用。非常感谢您能够解答一下

双读机制是怎么样的?

请问下双读的意思是随机读其中一边的key?还是同时读两边key,取最新的key?
若是同时读两边key,当其中一边删除后,应该如何读取?

有没有完善管理后台的计划

dashboard提供的功能过于简单,操作数据,很容易出错?有没有提供监控功能的计划呢?以后对于这个项目还有哪些功能的升级?

请问一下ReplyEncoder:channel not active是个什么错误

2021-02-24 05:41:27.934 ERROR 1 --- [pool-6-thread-1] c.n.n.c.r.proxy.util.ErrorLogCollector : com.netease.nim.camellia.redis.proxy.netty.ReplyEncoder:channel not active, remote.ip=/127.0.0.1:51147, count = 30

2021-02-24 05:41:27.934 ERROR 1 --- [pool-6-thread-1] c.n.n.c.r.proxy.util.ErrorLogCollector : com.netease.nim.camellia.redis.proxy.netty.ReplyEncoder:channel not active, remote.ip=/127.0.0.1:49193, count = 30

2021-02-24 05:41:27.934 ERROR 1 --- [pool-6-thread-1] c.n.n.c.r.proxy.util.ErrorLogCollector : com.netease.nim.camellia.redis.proxy.netty.ReplyEncoder:channel not active, remote.ip=/127.0.0.1:51941, count = 30

2021-02-24 05:41:27.934 ERROR 1 --- [pool-6-thread-1] c.n.n.c.r.proxy.util.ErrorLogCollector : com.netease.nim.camellia.redis.proxy.netty.ReplyEncoder:channel not active, remote.ip=/127.0.0.1:52119, count = 30

2021-02-24 05:41:27.934 ERROR 1 --- [pool-6-thread-1] c.n.n.c.r.proxy.util.ErrorLogCollector : com.netease.nim.camellia.redis.proxy.netty.ReplyEncoder:channel not active, remote.ip=/127.0.0.1:49754, count = 30

2021-02-24 05:41:27.934 ERROR 1 --- [pool-6-thread-1] c.n.n.c.r.proxy.util.ErrorLogCollector : com.netease.nim.camellia.redis.proxy.netty.ReplyEncoder:channel not active, remote.ip=/127.0.0.1:49872, count = 30

2021-02-24 05:41:27.934 ERROR 1 --- [pool-6-thread-1] c.n.n.c.r.proxy.util.ErrorLogCollector : com.netease.nim.camellia.redis.proxy.netty.ReplyEncoder:channel not active, remote.ip=/127.0.0.1:51707, count = 30

add log level check

com.netease.nim.camellia.redis.proxy.command.async.AsyncCamelliaSimpleClient#preheat
log some info, without any log level check

Fix Error Code API /permissions/ip-checkers

Update Error Code API /permission/ip-checkers
[x] Not Found Ip Checker configuration -> Error code: 404
[x] Check existed by bid and bgroup before updating the Ip-Checker (prevent update bid and bgroup)


My fault, I'm going to update those issues tonight or tomorrow.

Support for selecting other database by redis-proxy

Hello
Could someone explain why there is no support for selecting other database than 0?

Or maybe it is possible to get some workaround by setup database in "resource-table.json" file and launch few instances of redis-proxy (db0 on port 6000, db1 on port 6001 etc)?
For example, something like that:

server:
  port: 6002
spring:
  application:
    name: camellia-redis-proxy-server

camellia-redis-proxy:
  database: 2 # <---- here setup database id that is supported, default=0
  transpond:
    type: local
    local:
      type: complex
      json-file: /tmp/resource-table.json

and:

{
  "type": "simple",
  "operation": {
    "read": "redis://[email protected]:6379/2", # <--- here is "destination" database id
    "type": "rw_separate",
    "write": {
      "resources": [
        "redis://[email protected]:6379/2", # <--- here is "destination" database id
        "redis://[email protected]:6380/2", # <--- here is "destination" database id
      ],
      "type": "multi"
    }
  }
}

Thanks for help

Cannot test performance by redis-benchmark

Hi @caojiajun, I want to say camellia is an excellent project. Thank you all. <3

Follow by performance-report.md, I try to test performance by redis-benchmark, but I got an issue:

 ~ redis-benchmark -n 1000000 -r 10000 -c 200 -t set,get,incr,lpush,rpush,lpop,rpop,sadd,hset,spop,lpush,lrange -q -p 6380 -h [myhost] -a [pass]
ERROR: Not Support
ERROR: failed to fetch CONFIG from [myhost]:6380
WARNING: Could not fetch server CONFIG
SET: rps=0.0 (overall: 0.0) avg_msec=nan (overall: nan) 

and I read the code of this project do not support the CONFIG redis command:
CONFIG(CommandSupportType.NOT_SUPPORT, null, null, Blocking.FALSE, null),

How can you benchmark camellia-redis-proxy with redis-benchmark.

Again, Thank you so much!

[Camellia-redis-proxy] Maven dependency pulling a wrong dependency

I try to upgrade camellia to version v1.1.3, so I found an error Maven dependency pulling a wrong dependency (maybe since v.1.1.2, I test with v1.1.1 still works)

....
		<dependency>
			<groupId>com.netease.nim</groupId>
			<artifactId>camellia-redis-proxy-spring-boot-starter</artifactId>
			<version>1.1.3</version>
		</dependency>

....
  • V1.1.1:
    image

  • V1.1.3:
    image

==> The consequence is cannot load classes of camellia-redis-proxy module
image

关于密码部分的疑惑

你好,

我看到camellia redis proxy支持设定密码,我想了解对应redis cluster proxy里的auth口令部分,在camellia redis proxy中应该如何设置?

command return NOT_AVAILABLE

我后端对接的是pika 。报这个错误 有点不理解 。看连接 ,还连上来了,最后总是报这么个错误 。。。
ERROR error-log-collector-pool-7-thread-1 c.n.n.c.r.p.u.ErrorLogCollector:62 - com.netease.nim.camellia.redis.proxy.command.async.RedisClient:RedisClient[@10.10.251.11:6379][id=53] stopping, command return NOT_AVAILABLE, count = 1

redis proxy参数最佳实践

  1. 背景

redis proxy 作为一个大型redis cluster集群的proxy。
该cluster 为110个master 110个slave。
proxy节点数为10个节点。在客户端使用lettuce作为连接,并根据请求进行了负载均衡。
压测VUSER 1200

  1. 现象

压测到一定流量后,出现no child group等错误。该问题应该是netty的child group无法再处理了。

  1. 问题分析

发现在源码中 soBacklog的值设置为1024.该值在大集群海量并发情况下,是否合理?不确定该问题是否由这个设置导致的。

  1. 期望

是否可以提供一些针对不同场景的参数最佳实践?

关于不支持命令

你好,想请教下,目前不支持的命令比如DUMP这种,不支持的原因是什么呀?比如RESTORE命令?
我这边想用camellia做一对多数据同步的写通道,但是做全量同步的时候需要用到RESTORE命令。

Enhancement: Support connect limit for each tenant(bid, bgroup) by only 1 global configuration

Enhancement: Support connect limit for each tenant(bid, bgroup) by only 1 global configuration

We currently have the connect limit configuration for:

  • all tenants: max.client.connect=10000
  • each tenant by bid and bgroup: 1.default.max.client.connect=10000

Maybe we need to support config limit connection for each tenant by only 1 "global configuration":

  • Global tenant: bid=-1 & bgroup=default
  • -1.default.max.client.connect=10000 ==> this configuration will apply for all tenants if those are not set.

I will commit to this update today.

Dynamic update ip check proxy from camelliadashboard

hi @caojiajun,
Now we're having ipCheckerPlugin - A plugin for IP black and white list restrictions on clients accessing the proxy. But It still read the configuration from file camellia-redis-proxy.properties.
Should we provide a new Ip Checker Plugin: dynamicIpCheckerPlugin, It will read configurations via camellia-dashboard like how we fetch data from that. We will store these configurations in the database instead of a file.

create table camellia_ip_checker
(
    id          bigint(64) auto_increment comment 'Auto increment field'
        primary key,
    bid         bigint(64)    null comment 'bid',
    bgroup      varchar(64)   null comment 'bgroup',
    mode        tinyint(1)    not null comment '0=UNKNOWN, 1=BLACK, 2=WHITE',
    ip_list     varchar(1024) not null comment 'support ip, also supports network segment, comma separated.ex:2.2.2.2,5.5.5.5,3.3.3.0/24,6.6.0.0/16',
    create_time varchar(64)   null comment 'create time',
    update_time varchar(64)   null comment 'Update time',
    constraint bid_bgroup_unique
        unique (bid, bgroup)
)
    comment 'IP checker table' charset = utf8;

Database schema: Create/Update time is varchar?

CREATE TABLE `camellia_resource_info` (
  `id` bigint(64) NOT NULL primary key auto_increment comment '自增字段',
  `url` varchar(1024) NOT NULL comment '资源url',
  `info` varchar(1024) NOT NULL comment '描述',
  `tids` varchar(1024) DEFAULT NULL comment '引用的tids',
  `create_time` varchar(2000) DEFAULT NULL comment '创建时间',
  `update_time` varchar(64) DEFAULT NULL comment '更新时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='资源信息表';

As the title, why are data types 'create_timeand update_time` varchar?

[Camellia-redis-proxy] How to add a custom header into CamelliaApi: api-key

Camellia-dashboard: I implement api-key authentication. Every request must have the header api-key: xxx for more security.

Camellia-redis-proxy: I don't want to modify your code, how can I override Request Interceptor of CamelliaApi (2 methods: getResourceTable() , reportStats())

I saw your code init Camellia Feign Client inside CamelliaApiUtil:

public class CamelliaApiUtil {

    public static CamelliaApi init(String url, int connectTimeoutMillis, int readTimeoutMillis) {
        return Feign.builder()
                .encoder(new JacksonEncoder())
                .decoder(new JacksonDecoder())
                .requestInterceptor(template -> {
                    if (CamelliaApiEnv.source != null) {
                        template.header(CamelliaApiEnv.REQUEST_SOURCE, CamelliaApiEnv.source);
                    }
                })
                .options(new Request.Options(connectTimeoutMillis, readTimeoutMillis))
                .target(CamelliaApi.class, url);
    }
}

But it is not Bean, so I cannot override it or add Request Interceptor like that:

    @Bean
    public RequestInterceptor myCustomInterceptor() {
        return template->template.header("api-key", "xxx");
    }

I suggest a feature that we can config headers inside transpond RemoteProperties:

application.yaml

camellia-redis-proxy:
  transpond:
    type: remote
    remote: 
      url: ${CAMELLIA_DASHBOARD_URL:http://127.0.0.1:8080} #camellia-dashboard's address
      check-interval-millis: ${REMOTE_CHECK_INTERVAL_MILLIS:5000} # Polling period to camellia-dashboard
      dynamic: ${REMOTE_DYNAMIC:true} # indicates that multiple sets of configurations are supported, the default is true
      api-key-header-name: ${REMOTE_API_KEY_HEADER_NAME:api-key} # API Key header name
      api-key: ${REMOTE_API_KEY:xxx} # API Key

And add it inside :

public class CamelliaApiUtil {

    public static CamelliaApi init(String url, String apiKeyHeaderName, String apiKey, int connectTimeoutMillis, int readTimeoutMillis) {
        return Feign.builder()
                .encoder(new JacksonEncoder())
                .decoder(new JacksonDecoder())
                .requestInterceptor(template -> {
                    if (CamelliaApiEnv.source != null) {
                        template.header(CamelliaApiEnv.REQUEST_SOURCE, CamelliaApiEnv.source);
                    }
                    if(apiKeyHeaderName != null){ // <-------------------------------------------this
                        template.header(apiKeyHeaderName, apiKey);
                    }
                })
                .options(new Request.Options(connectTimeoutMillis, readTimeoutMillis))
                .target(CamelliaApi.class, url);
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.