Giter VIP home page Giter VIP logo

java-redis-client's Introduction

Build Status Coverage Status Released Version Apache-2.0 license

OpenTracing Redis Client Instrumentation

OpenTracing instrumentation for Redis Client

Requirements

  • Java 8

Installation

Jedis

Jedis 2

pom.xml

<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-redis-jedis</artifactId>
    <version>VERSION</version>
</dependency>

Jedis 3

pom.xml

<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-redis-jedis3</artifactId>
    <version>VERSION</version>
</dependency>

Lettuce

pom.xml

<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-redis-lettuce-5.2</artifactId>
    <version>VERSION</version>
</dependency>

Redisson

pom.xml

<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-redis-redisson</artifactId>
    <version>VERSION</version>
</dependency>

Spring Data Redis 1.x

pom.xml

<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-redis-spring-data</artifactId>
    <version>VERSION</version>
</dependency>

Spring Data Redis 2.x

pom.xml

<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-redis-spring-data2</artifactId>
    <version>VERSION</version>
</dependency>

Usage

// Instantiate tracer
Tracer tracer = ...

// Create TracingConfiguration
TracingConfiguration tracingConfiguration = new TracingConfiguration.Builder(tracer).build(); 

Jedis

// Create Tracing Jedis
Jedis jedis = new TracingJedis(tracingConfiguration);

jedis.set("foo", "bar");
String value = jedis.get("foo");

Jedis Cluster

Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7379));

// Create Tracing Jedis Cluster
JedisCluster jc = new TracingJedisCluster(jedisClusterNodes, tracingConfiguration);
jc.set("foo", "bar");
String value = jc.get("foo");

Jedis Pool

// Configure the pool
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(10);
poolConfig.setTestOnBorrow(false);

// Create Tracing Jedis Pool
JedisPool pool = new TracingJedisPool(poolConfig, "127.0.0.1", 6379, tracingConfiguration);

try (Jedis jedis = pool.getResource()) {
    // jedis will be automatically closed and returned to the pool at the end of "try" block
    jedis.set("foo", "bar");
    String value = jedis.get("foo");
}

Jedis Sentinel Pool

// Create Tracing Jedis Sentinel Pool
JedisSentinelPool pool = new TracingJedisSentinelPool(tracingConfiguration, MASTER_NAME, sentinels, poolConfig);

try (Jedis jedis = pool.getResource()) {
// jedis will be automatically closed and returned to the pool at the end of "try" block
   jedis.set("foo", "bar"));
   String value = jedis.get("foo"));
}

Jedis Span Name

By default, span names are set to the operation performed by the Jedis object. To customize the span name, provide a Function to the TracingConfiguration object that alters the span name. If a function is not provided, the span name will remain the default. Refer to the RedisSpanNameProvider class for a function that prefixes the operation name.

TracingConfiguration tracingConfiguration = new TracingConfiguration.Builder(tracer)
    .withSpanNameProvider(RedisSpanNameProvider.PREFIX_OPERATION_NAME("redis."))
    .build(); 
//Create Tracing Jedis with custom span name
Jedis jedis = new TracingJedis(tracingConfiguration);
jedis.set("foo", "bar");
//Span name is now set to "redis.set"

Lettuce

// Create client
RedisClient client = RedisClient.create("redis://localhost");

// Decorate StatefulRedisConnection with TracingStatefulRedisConnection
StatefulRedisConnection<String, String> connection = 
    new TracingStatefulRedisConnection(client.connect(), tracingConfiguration);

// Get sync redis commands
RedisCommands<String, String> commands = connection.sync();

// Get async redis commands
RedisAsyncCommands<String, String> commandsAsync = connection.async();

Redisson

// Create Redisson config object
Config = ...

// Create Redisson instance
RedissonClient redissonClient = Redisson.create(config);

// Decorate RedissonClient with TracingRedissonClient
RedissonClient tracingRedissonClient =  new TracingRedissonClient(redissonClient, tracingConfiguration);

// Get object you need using TracingRedissonClient
RMap<MyKey, MyValue> map = tracingRedissonClient.getMap("myMap");

Spring

// Create tracing connection factory bean
@Bean
public RedisConnectionFactory redisConnectionFactory() {
    LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory();
    lettuceConnectionFactory.afterPropertiesSet();
    return new TracingRedisConnectionFactory(lettuceConnectionFactory,
        new TracingConfiguration.Builder(tracer()).build());
}

Note: if you use Lettuce/Jedis you could achieve the same result using the Lettuce/Jedis support when configuring LettuceConnectionFactory/JedisConnectionFactory instead of using a wrapping TracingRedisConnectionFactory.

License

Apache 2.0 License.

java-redis-client's People

Contributors

antonfilatov avatar avnandu avatar chenziyu avatar ddcprg avatar dengliming avatar duoyuli avatar elgris avatar fujigon avatar huangxfchn avatar jonlockwood avatar kasinskim avatar malafeev avatar natheee avatar pikbot avatar rjricken avatar safris 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

Watchers

 avatar  avatar  avatar  avatar

java-redis-client's Issues

Redis springboot starter

opentracing-redis-spring module has supported spring. so can we support spring boot in the form of springboot starter

opentracing-redis-spring-data2 doesn't support health check

description

  • spring boot 2.1.3, opentracing-redis-spring-data2 0.1.2
  • when spring actuate redis do health check, then trigger Redis health check failed java.lang.IllegalArgumentException

the reason

io.opentracing.contrib.redis.spring.data2.connection.TracingRedisConnectionFactory#getConnection() does not determine if it is RedisClusterConnection, and org.springframework.data.redis.connection.jedis.JedisConnectionFactory#getConnection() Will return RedisClusterConnection, but TracingRedisConnectionFactory will still be wrapped into a non-clustered RedisConnection

When spring actuate does a health check on redis, it will determine whether it is a RedisClusterConnection, org.springframework.boot.actuate.redis.RedisHealthIndicator#doHealthCheck key code is as follows, will be mistaken for non-clustered links.

if (connection instanceof RedisClusterConnection) {
	ClusterInfo clusterInfo = ((RedisClusterConnection) connection).clusterGetClusterInfo();
	builder.up().withDetail("cluster_size", clusterInfo.getClusterSize())
			.withDetail("slots_up", clusterInfo.getSlotsOk())
			.withDetail("slots_fail", clusterInfo.getSlotsFail());
}
else {
	Properties info = connection.info();
	builder.up().withDetail(VERSION, info.getProperty(REDIS_VERSION));
}

the solution

Modify the TracingRedisConnectionFactory code to increase the judgment of RedisClusterConnection

@Override
public RedisConnection getConnection() {
    RedisConnection connection = this.connectionFactory.getConnection();
    if ( connection instanceof RedisClusterConnection) {
        return new TracingRedisClusterConnection((RedisClusterConnection)connection, tracingConfiguration);
    }
    return new TracingRedisConnection(connection, tracingConfiguration);
}

@Override
public ReactiveRedisConnection getReactiveConnection() {
    if (connectionFactory instanceof ReactiveRedisConnectionFactory) {
        ReactiveRedisConnection connection = ((ReactiveRedisConnectionFactory) connectionFactory).getReactiveConnection();
        if ( connection instanceof ReactiveRedisClusterConnection) {
            return new TracingReactiveRedisClusterConnection((ReactiveRedisClusterConnection)connection, tracingConfiguration);
        }
        return new TracingReactiveRedisConnection(((ReactiveRedisConnectionFactory) connectionFactory).getReactiveConnection(), tracingConfiguration);
    }
    return null;
}

exception stacktrace

Redis health check failed java.lang.IllegalArgumentException: Value must not be null
	at org.springframework.util.Assert.notNull(Assert.java:198)
	at org.springframework.boot.actuate.health.Health$Builder.withDetail(Health.java:228)
	at org.springframework.boot.actuate.redis.RedisHealthIndicator.doHealthCheck(RedisHealthIndicator.java:67)
	at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:84)
	at org.springframework.boot.actuate.health.CompositeHealthIndicator.health(CompositeHealthIndicator.java:98)
	at org.springframework.boot.actuate.health.HealthEndpoint.health(HealthEndpoint.java:50)
	at org.springframework.boot.actuate.health.HealthEndpointWebExtension.health(HealthEndpointWebExtension.java:54)

opentracing-redis-spring can not work with springboot 1.5x

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jedisConnectionFactory' defined in class path resource [com/gridsum/config/RedisConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.redis.connection.RedisConnectionFactory]: Factory method 'jedisConnectionFactory' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/data/redis/connection/ReactiveRedisConnectionFactory
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
	... 32 common frames omitted

The ReactiveRedisConnectionFactory class is not in springboot 1.5x

Redis keys length should be limited

@Override
public List<String> mget(String... keys) {
Span span = helper.buildSpan("mget", keys);
try {
return super.mget(keys);
} catch (Exception e) {
onError(e, span);
throw e;
} finally {
span.finish();
}
}

When client invoked mget function,and keys length is more than hundred or more,then the span data will be so big so that it will cost so much to transport the span data and to store span data.I think it will be a little help and cost so much. so i suppose there should be a limited length.

the same to the other functions releated many keys

opentracing-redis-spring doesn't support ReactiveRedisConnectionFactory

I try to use opentracing-redis-spring in an spring boot application like this:

@Component
public class RedisConnectionFactoryBeanPostProcessor implements BeanPostProcessor {

  private Tracer tracer;

  public RedisConnectionFactoryBeanPostProcessor(Tracer tracer) {
    this.tracer = tracer;
  }

  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof RedisConnectionFactory) {
      return new TracingRedisConnectionFactory((RedisConnectionFactory) bean, false, tracer);
    }
    return bean;
  }
}

And I got this error:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'reactiveRedisTemplate' defined in class path resource [org/springframework/boot/autoconfigure/data/redis/RedisReactiveAutoConfiguration.class]: Unsatisfied dependency expressed through method 'reactiveRedisTemplate' parameter 0; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'redisConnectionFactory' is expected to be of type 'org.springframework.data.redis.connection.ReactiveRedisConnectionFactory' but was actually of type 'io.opentracing.contrib.redis.spring.connection.TracingRedisConnectionFactory'
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'redisConnectionFactory' is expected to be of type 'org.springframework.data.redis.connection.ReactiveRedisConnectionFactory' but was actually of type 'io.opentracing.contrib.redis.spring.connection.TracingRedisConnectionFactory'

I found that TracingRedisConnectionFactory only implements RedisConnectionFactory while spring-boot-starter-data-redis auto configures an LettuceConnectionFactory by default which also implements ReactiveRedisConnectionFactory and that's why the error appears.

Support for Lettuce 6.0.1

Hi, just wanted to check if the current opentracing-redis-lettuce-5.2 will support lettuce 6.0.1

lettuce 6.0.1 is being shipped by default with SB 2.4.0 spring-data-redis

opentracing-redis-jedis replace jedis in spring container

I want to replace the original JedisPool in my project with opentracing-redis-jedis instrument

Try to use BeanPostProcessor in this case as below. But can't get the params of original JedisPool to init TracingJedisPool.

public class JedisPoolTracingBeanPostProcessor implements BeanPostProcessor {
    private Tracer tracer;

    private boolean withActiveSpanOnly;

    public JedisPoolTracingBeanPostProcessor(Tracer tracer, boolean withActiveSpanOnly) {
        super();
        this.tracer = tracer;
        this.withActiveSpanOnly = withActiveSpanOnly;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (this.tracer != null && bean instanceof JedisPool && !(bean instanceof TracingJedisPool)) {
            JedisPool origin = (JedisPool) bean;
            if (origin instanceof InitializingBean) {
                try {
                    ((InitializingBean) origin).afterPropertiesSet();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }

            // Create TracingConfiguration
            TracingConfiguration tracingConfiguration = new TracingConfiguration.Builder(GlobalTracer.get()).build();

            // Create Tracing Jedis Pool
            return new TracingJedisPool("",6379, tracingConfiguration);
        }
        return bean;
    }
}

How can i init TracingJedisPool elegantly?

spring redis support redis key tag

I find TracingJedis has now supported the redis key tag but the spring redis does not support the redis key tag.

As for me .the redis key tag is very import for developer to survey the problem.

so could the spring reids support the redis key tag?

jedis cluster get connection error

Hi,when i do tracing with redis,there is a problem.
my config is :
@bean
public RedisConnectionFactory connectionFactory() {

    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    jedisPoolConfig.setMaxTotal(100);
    jedisPoolConfig.setMaxIdle(50);
    jedisPoolConfig.setMinIdle(20);
    jedisPoolConfig.setMaxWaitMillis(200);
    jedisPoolConfig.setTestOnBorrow(true);
    jedisPoolConfig.setTestOnReturn(true);
    jedisPoolConfig.setTestWhileIdle(true);

    JedisClientConfiguration clientConfig = JedisClientConfiguration.builder()
            .connectTimeout(Duration.ofMillis(20))
            .readTimeout(Duration.ofMillis(20)).usePooling().poolConfig(jedisPoolConfig)
            .build();
    if(redisContants.REDIS_TYPE.equals("single")) {
        RedisStandaloneConfiguration  redisConfiguration=new RedisStandaloneConfiguration(redisContants.REDIS_HOST.split(":")[0], redisContants.REDIS_PORT);
        //return new JedisConnectionFactory(new RedisStandaloneConfiguration(redisContants.REDIS_HOST.split(":")[0], redisContants.REDIS_PORT),clientConfig);
        return new TracingRedisConnectionFactory(new JedisConnectionFactory(redisConfiguration,clientConfig), new TracingConfiguration.Builder(tracer).build());
    }else {
        RedisClusterConfiguration redisClusterConfiguration= new RedisClusterConfiguration(clusterProperties.getNodes());
        return new TracingRedisConnectionFactory(new JedisConnectionFactory(redisClusterConfiguration, clientConfig), new TracingConfiguration.Builder(tracer).build());
       //return new JedisConnectionFactory(new RedisClusterConfiguration(clusterProperties.getNodes()), clientConfig);
    }
}

witnout tracing, everything works! when i do tracing in test env,this is standalone mode,this works too,when do it in cluster env,cannt get a jedis cluster connection.when i debug it,find spring redistemplate get a connection from a method called getconnection,just like jedis ,but there TracingRedisFactory class only do the right thing in standalone mode,do it should implement a method like jedisFactory .
public boolean isRedisClusterAware() {
return RedisConfiguration.isClusterConfiguration(configuration);
}

TracingRedisConnection not working with Spring-Boot 2.5.x

Hi,

after upgrading a project to Spring-Boot 2.5.x we get errors like the following:

java.lang.AbstractMethodError: Receiver class io.opentracing.contrib.redis.spring.data2.connection.TracingRedisConnection does not define or inherit an implementation of the resolved method 'java.lang.Boolean zAdd(byte[], double, byte[], org.springframework.data.redis.connection.RedisZSetCommands$ZAddArgs)' of interface org.springframework.data.redis.connection.RedisConnection.
	at org.springframework.data.redis.connection.DefaultStringRedisConnection.zAdd(DefaultStringRedisConnection.java:1338)
	at org.springframework.data.redis.connection.RedisZSetCommands.zAdd(RedisZSetCommands.java:569)
	at org.springframework.data.redis.core.DefaultZSetOperations.lambda$add$0(DefaultZSetOperations.java:56)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:222)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:189)
	at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:96)
	at org.springframework.data.redis.core.DefaultZSetOperations.add(DefaultZSetOperations.java:56)

It seems this project is not really up-to-date anymore given that it's on Spring-Boot 2.2.x. Is there any alternative project that we could go for?

Cheers,
Christoph

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.