{"id":2045,"date":"2023-04-01T20:51:47","date_gmt":"2023-04-01T12:51:47","guid":{"rendered":"https:\/\/www.appblog.cn\/?p=2045"},"modified":"2023-04-07T06:11:09","modified_gmt":"2023-04-06T22:11:09","slug":"spring-boot-integration-redisson-single-machine-cluster-sentry","status":"publish","type":"post","link":"https:\/\/www.appblog.cn\/index.php\/2023\/04\/01\/spring-boot-integration-redisson-single-machine-cluster-sentry\/","title":{"rendered":"Spring Boot\u96c6\u6210Redisson(\u5355\u673a,\u96c6\u7fa4,\u54e8\u5175)"},"content":{"rendered":"<h2>Maven\u4f9d\u8d56<\/h2>\n<pre><code class=\"language-xml\">&lt;!-- https:\/\/mvnrepository.com\/artifact\/org.redisson\/redisson --&gt;\n&lt;dependency&gt;\n    &lt;groupId&gt;org.redisson&lt;\/groupId&gt;\n    &lt;artifactId&gt;redisson&lt;\/artifactId&gt;\n    &lt;version&gt;3.10.5&lt;\/version&gt;\n&lt;\/dependency&gt;<\/code><\/pre>\n<p><!-- more --><\/p>\n<h2>\u914d\u7f6e\u6587\u4ef6<\/h2>\n<p>application.properties<\/p>\n<pre><code>spring.redis.database=0\nspring.redis.password=\nspring.redis.timeout=3000\n#sentinel\/cluster\/single\nspring.redis.mode=single\n#\u8fde\u63a5\u6c60\u914d\u7f6e\nspring.redis.pool.max-idle=16\nspring.redis.pool.min-idle=8\nspring.redis.pool.max-active=8\nspring.redis.pool.max-wait=3000\nspring.redis.pool.conn-timeout=3000\nspring.redis.pool.so-timeout=3000\nspring.redis.pool.size=10\n#\u5355\u673a\u914d\u7f6e\nspring.redis.single.address=127.0.0.1:6379\n#\u96c6\u7fa4\u914d\u7f6e\nspring.redis.cluster.scan-interval=1000\nspring.redis.cluster.nodes=\nspring.redis.cluster.read-mode=SLAVE\nspring.redis.cluster.retry-attempts=3\nspring.redis.cluster.failed-attempts=3\nspring.redis.cluster.slave-connection-pool-size=64\nspring.redis.cluster.master-connection-pool-size=64\nspring.redis.cluster.retry-interval=1500\n#\u54e8\u5175\u914d\u7f6e\nspring.redis.sentinel.master=business-master\nspring.redis.sentinel.nodes=\nspring.redis.sentinel.master-onlyWrite=true\nspring.redis.sentinel.fail-max=3<\/code><\/pre>\n<h2>\u914d\u7f6e\u6587\u4ef6\u8bfb\u53d6<\/h2>\n<p>RedisProperties.java<\/p>\n<pre><code class=\"language-java\">import lombok.Data;\nimport lombok.ToString;\nimport org.springframework.boot.context.properties.ConfigurationProperties;\n\n@ConfigurationProperties(prefix = &quot;spring.redis&quot;, ignoreUnknownFields = false)\n@Data\n@ToString\npublic class RedisProperties {\n\n    private int database;\n\n    \/**\n     * \u7b49\u5f85\u8282\u70b9\u56de\u590d\u547d\u4ee4\u7684\u65f6\u95f4\uff0c\u8be5\u65f6\u95f4\u4ece\u547d\u4ee4\u53d1\u9001\u6210\u529f\u65f6\u5f00\u59cb\u8ba1\u65f6\n     *\/\n    private int timeout;\n\n    private String password;\n\n    private String mode;\n\n    \/**\n     * \u6c60\u914d\u7f6e\n     *\/\n    private RedisPoolProperties pool;\n\n    \/**\n     * \u5355\u673a\u4fe1\u606f\u914d\u7f6e\n     *\/\n    private RedisSingleProperties single;\n\n    \/**\n     * \u96c6\u7fa4\u4fe1\u606f\u914d\u7f6e\n     *\/\n    private RedisClusterProperties cluster;\n\n    \/**\n     * \u54e8\u5175\u914d\u7f6e\n     *\/\n    private RedisSentinelProperties sentinel;\n}<\/code><\/pre>\n<h3>Redis\u6c60\u914d\u7f6e<\/h3>\n<p>RedisPoolProperties.java<\/p>\n<pre><code class=\"language-java\">import lombok.Data;\nimport lombok.ToString;\n\n@Data\n@ToString\npublic class RedisPoolProperties {\n\n    private int maxIdle;\n\n    private int minIdle;\n\n    private int maxActive;\n\n    private int maxWait;\n\n    private int connTimeout;\n\n    private int soTimeout;\n\n    \/**\n     * \u6c60\u5927\u5c0f\n     *\/\n    private int size;\n}<\/code><\/pre>\n<h3>\u5355\u673a\u914d\u7f6e<\/h3>\n<p>RedisSingleProperties.java<\/p>\n<pre><code class=\"language-java\">@Data\n@ToString\npublic class RedisSingleProperties {\n    private String address;\n}<\/code><\/pre>\n<h3>\u96c6\u7fa4\u914d\u7f6e<\/h3>\n<p>RedisClusterProperties.java<\/p>\n<pre><code class=\"language-java\">@Data\n@ToString\npublic class RedisClusterProperties {\n\n    \/**\n     * \u96c6\u7fa4\u72b6\u6001\u626b\u63cf\u95f4\u9694\u65f6\u95f4\uff0c\u5355\u4f4d\u662f\u6beb\u79d2\n     *\/\n    private int scanInterval;\n\n    \/**\n     * \u96c6\u7fa4\u8282\u70b9\n     *\/\n    private String nodes;\n\n    \/**\n     * \u9ed8\u8ba4\u503c\uff1aSLAVE\uff08\u53ea\u5728\u4ece\u670d\u52a1\u8282\u70b9\u91cc\u8bfb\u53d6\uff09\u8bbe\u7f6e\u8bfb\u53d6\u64cd\u4f5c\u9009\u62e9\u8282\u70b9\u7684\u6a21\u5f0f\u3002\u53ef\u7528\u503c\u4e3a\uff1aSLAVE - \u53ea\u5728\u4ece\u670d\u52a1\u8282\u70b9\u91cc\u8bfb\u53d6\uff1b\n     * MASTER - \u53ea\u5728\u4e3b\u670d\u52a1\u8282\u70b9\u91cc\u8bfb\u53d6\uff1bMASTER_SLAVE - \u5728\u4e3b\u4ece\u670d\u52a1\u8282\u70b9\u91cc\u90fd\u53ef\u4ee5\u8bfb\u53d6\n     *\/\n    private String readMode;\n    \/**\n     * \u4ece\u8282\u70b9\u8fde\u63a5\u6c60\u5927\u5c0f\uff0c\u9ed8\u8ba4\u503c\uff1a64\n     *\/\n    private int slaveConnectionPoolSize;\n    \/**\n     * \u4e3b\u8282\u70b9\u8fde\u63a5\u6c60\u5927\u5c0f\uff0c\u9ed8\u8ba4\u503c\uff1a64\n     *\/\n    private int masterConnectionPoolSize;\n\n    \/**\n     * \u547d\u4ee4\u5931\u8d25\u91cd\u8bd5\u6b21\u6570\uff0c\u9ed8\u8ba4\u503c\uff1a3\n     *\/\n    private int retryAttempts;\n\n    \/**\n     * \u547d\u4ee4\u91cd\u8bd5\u53d1\u9001\u65f6\u95f4\u95f4\u9694\uff0c\u5355\u4f4d\uff1a\u6beb\u79d2\uff0c\u9ed8\u8ba4\u503c\uff1a1500\n     *\/\n    private int retryInterval;\n\n    \/**\n     * \u6267\u884c\u5931\u8d25\u6700\u5927\u6b21\u6570\u9ed8\u8ba4\u503c\uff1a3\n     *\/\n    private int failedAttempts;\n}<\/code><\/pre>\n<h3>\u54e8\u5175\u914d\u7f6e<\/h3>\n<p>RedisSentinelProperties.java<\/p>\n<pre><code class=\"language-java\">@Data\n@ToString\npublic class RedisSentinelProperties {\n\n    \/**\n     * \u54e8\u5175master \u540d\u79f0\n     *\/\n    private String master;\n\n    \/**\n     * \u54e8\u5175\u8282\u70b9\n     *\/\n    private String nodes;\n\n    \/**\n     * \u54e8\u5175\u914d\u7f6e\n     *\/\n    private boolean masterOnlyWrite;\n\n    \/**\n     *\n     *\/\n    private int failMax;\n}<\/code><\/pre>\n<h2>CacheConfiguration<\/h2>\n<pre><code class=\"language-java\">@Configuration\n@EnableConfigurationProperties(RedisProperties.class)\npublic class CacheConfiguration {\n\n    @Autowired\n    RedisProperties redisProperties;\n\n    @Configuration\n    @ConditionalOnClass({Redisson.class})\n    @ConditionalOnExpression(&quot;&#039;${spring.redis.mode}&#039;==&#039;single&#039; or &#039;${spring.redis.mode}&#039;==&#039;cluster&#039; or &#039;${spring.redis.mode}&#039;==&#039;sentinel&#039;&quot;)\n    protected class RedissonSingleClientConfiguration {\n\n        \/**\n         * \u5355\u673a\u6a21\u5f0f redisson \u5ba2\u6237\u7aef\n         *\/\n        @Bean\n        @ConditionalOnProperty(name = &quot;spring.redis.mode&quot;, havingValue = &quot;single&quot;)\n        RedissonClient redissonSingle() {\n            Config config = new Config();\n            String node = redisProperties.getSingle().getAddress();\n            node = node.startsWith(&quot;redis:\/\/&quot;) ? node : &quot;redis:\/\/&quot; + node;\n            SingleServerConfig serverConfig = config.useSingleServer()\n                    .setAddress(node)\n                    .setTimeout(redisProperties.getPool().getConnTimeout())\n                    .setConnectionPoolSize(redisProperties.getPool().getSize())\n                    .setConnectionMinimumIdleSize(redisProperties.getPool().getMinIdle());\n            if (StringUtils.isNotBlank(redisProperties.getPassword())) {\n                serverConfig.setPassword(redisProperties.getPassword());\n            }\n            return Redisson.create(config);\n        }\n\n        \/**\n         * \u96c6\u7fa4\u6a21\u5f0f\u7684 redisson \u5ba2\u6237\u7aef\n         *\n         * @return\n         *\/\n        @Bean\n        @ConditionalOnProperty(name = &quot;spring.redis.mode&quot;, havingValue = &quot;cluster&quot;)\n        RedissonClient redissonCluster() {\n            System.out.println(&quot;cluster redisProperties:&quot; + redisProperties.getCluster());\n\n            Config config = new Config();\n            String[] nodes = redisProperties.getCluster().getNodes().split(&quot;,&quot;);\n            List&lt;String&gt; newNodes = new ArrayList(nodes.length);\n            Arrays.stream(nodes).forEach((index) -&gt; newNodes.add(\n                    index.startsWith(&quot;redis:\/\/&quot;) ? index : &quot;redis:\/\/&quot; + index));\n\n            ClusterServersConfig serverConfig = config.useClusterServers()\n                    .addNodeAddress(newNodes.toArray(new String[0]))\n                    .setScanInterval(\n                            redisProperties.getCluster().getScanInterval())\n                    .setIdleConnectionTimeout(\n                            redisProperties.getPool().getSoTimeout())\n                    .setConnectTimeout(\n                            redisProperties.getPool().getConnTimeout())\n                    .setFailedAttempts(\n                            redisProperties.getCluster().getFailedAttempts())\n                    .setRetryAttempts(\n                            redisProperties.getCluster().getRetryAttempts())\n                    .setRetryInterval(\n                            redisProperties.getCluster().getRetryInterval())\n                    .setMasterConnectionPoolSize(redisProperties.getCluster()\n                            .getMasterConnectionPoolSize())\n                    .setSlaveConnectionPoolSize(redisProperties.getCluster()\n                            .getSlaveConnectionPoolSize())\n                    .setTimeout(redisProperties.getTimeout());\n            if (StringUtils.isNotBlank(redisProperties.getPassword())) {\n                serverConfig.setPassword(redisProperties.getPassword());\n            }\n            return Redisson.create(config);\n        }\n\n       \/**  \n         * \u54e8\u5175\u6a21\u5f0f redisson \u5ba2\u6237\u7aef\n         * @return\n         *\/\n        @Bean\n        @ConditionalOnProperty(name = &quot;spring.redis.mode&quot;, havingValue = &quot;sentinel&quot;)\n        RedissonClient redissonSentinel() {\n            System.out.println(&quot;sentinel redisProperties:&quot; + redisProperties.getSentinel());\n            Config config = new Config();\n            String[] nodes = redisProperties.getSentinel().getNodes().split(&quot;,&quot;);\n            List&lt;String&gt; newNodes = new ArrayList(nodes.length);\n            Arrays.stream(nodes).forEach((index) -&gt; newNodes.add(\n                    index.startsWith(&quot;redis:\/\/&quot;) ? index : &quot;redis:\/\/&quot; + index));\n\n            SentinelServersConfig serverConfig = config.useSentinelServers()\n                    .addSentinelAddress(newNodes.toArray(new String[0]))\n                    .setMasterName(redisProperties.getSentinel().getMaster())\n                    .setReadMode(ReadMode.SLAVE)\n                    .setFailedAttempts(redisProperties.getSentinel().getFailMax())\n                    .setTimeout(redisProperties.getTimeout())\n                    .setMasterConnectionPoolSize(redisProperties.getPool().getSize())\n                    .setSlaveConnectionPoolSize(redisProperties.getPool().getSize());\n\n            if (StringUtils.isNotBlank(redisProperties.getPassword())) {\n                serverConfig.setPassword(redisProperties.getPassword());\n            }\n\n            return Redisson.create(config);\n        }\n    }\n}<\/code><\/pre>\n<h2>\u4f7f\u7528\u65f6\u5019\u76f4\u63a5\u6ce8\u5165RedissClient\u5ba2\u6237\u7aef\u5c31\u53ef\u4ee5\u4f7f\u7528<\/h2>\n<p>\u5982\u4e0b\u5199\u6cd5\u7684\u76ee\u7684\u662f\u4e3a\u4e86\u7edf\u4e00\u7ed9\u5176\u5b83\u670d\u52a1\u63d0\u4f9b\u63a5\u53e3<\/p>\n<pre><code class=\"language-java\">@Autowired\nRedissonClient redisson;\n\n@RequestMapping(value = &quot;lock&quot;, method = RequestMethod.POST, consumes = &quot;application\/json;charset=UTF-8&quot;, produces = &quot;application\/json;charset=UTF-8&quot;)\npublic @ResponseBody ServerResponse&lt;RLock&gt; lock(@RequestBody ServerRequest&lt;LockReqBody&gt; req) {\n    return callR(redisson -&gt; {\n        RLock lock = redisson.getLock(req.getReqBody().getLockKey());\n        lock.lock(req.getReqBody().getTimeout(), req.getReqBody().getUnit());\n        return lock;\n    });\n}\n\n\/\/\u7701\u7565\u90e8\u5206\u4ee3\u7801\nprivate &lt;R&gt; ServerResponse callR(Function&lt;RedissonClient, R&gt; function) {\n    ServerResponse dv = RespHelper.serverResponse(RespCodeService.ERROR, &quot;&quot;);\n    try {\n        long startTime = System.currentTimeMillis();\n        dv = RespHelper.serverResponse(RespCodeService.SUCCESS, function.apply(redisson));\n        logger.info(&quot;CALLR METHOD USE TIME: {}&quot;, System.currentTimeMillis() - startTime);\n    } catch (Throwable e) {          \n        System.out.println(&quot;callR error&quot;);\n    }\n    return dv;\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Maven\u4f9d\u8d56 &lt;!&#8211; https:\/\/mvnrepository.com\/artifact\/org. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41],"tags":[105],"class_list":["post-2045","post","type-post","status-publish","format-standard","hentry","category-spring-boot","tag-redisson"],"_links":{"self":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/2045","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/comments?post=2045"}],"version-history":[{"count":0,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/2045\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/media?parent=2045"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/categories?post=2045"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/tags?post=2045"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}