springboot + 读写分离+redis集群+集群部署

2023-11-09

记录一次 集群部署springboot 项目

1、nginx

使用 upstream 进行集群管理

upstream  serviceGroup{
  server 127.0.0.1:9090;
  server xxxxx:9090;
  server xxxx:9090;
}


server{
    xxxx
    ...
    location /api {
        proxy_set_header X-forwarded-for $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass    http://serviceGroup;
    }
}

2、redis

1、redis 一台机器最少两个节点,一主一从,3台机器组成3主3从

2、以宝塔为例子:宝塔安装redis后,进入安装目录 /www/server/redis

3、安装文件夹 clusters 进入后分别创建对应节点文件夹,如:1101 1102 两个端口实例文件夹,每个文件夹中创建 redis.conf 文件

bind 0.0.0.0
# 修改对应文件夹的端口号
port 1101
daemonize yes
requirepass "12345"
logfile "./redis.log"
dbfilename "dupm.rdb"
dir "/www/server/redis/clusters/1101"
masterauth "12345"
 
# 是否开启集群
cluster-enabled yes
# 生成的node文件,记录集群节点信息,默认为nodes.conf,会自动生成
cluster-config-file nodes.conf
#节点连接超时时间
cluster-node-timeout 15000
#对外的ip
cluster-announce-ip xx.xxx.xxx.xxx  公网地址
#集群节点映射端口
cluster-announce-port 1101
#集群节点总线端口,节点之间互相通信,常规端口+1万,用port + 10000
cluster-announce-bus-port 11101

在 1101 和 1102 下面都分别创建这个文件,内容一样 就修改端口,其他服务器也直接复制

4、分别启动这两个实例

./src/redis-server ./clusters/1101/redis.conf
./src/redis-server ./clusters/1102/redis.conf

5、启动后查询是否启动成功

ps -aux | grep redis

6、检查所有机器都启动成功后,选择其中一台创建集群,内网和公网IP都行

./src/redis-cli -a 12345 -p 1101 --cluster-replicas 1 --cluster create 机器IP:1101 机器IP:1102 机器IP:1101 机器IP:1102 机器IP:1101 机器IP:1102
  • 执行后要输入一个yes 进行确认

8、开放端口

firewall-cmd --zone=public --add-port=1101/tcp --permanent
firewall-cmd --zone=public --add-port=1102/tcp --permanent
firewall-cmd --zone=public --add-port=11101/tcp --permanent
firewall-cmd --zone=public --add-port=11102/tcp --permanent
#重新加载防火墙设置,使配置生效
firewall-cmd --reload

快速启动停止脚本:

start-redis-node.sh

#!/bin/bash
cd /www/server/redis
./src/redis-server ./clusters/1101/redis.conf
./src/redis-server ./clusters/1102/redis.conf
exit

stop-redis-node.sh

#!/bin/bash
PORT=($1 $2)
 
for port in ${PORT[@]}
do
PID=$(netstat -ntulp | grep :$port | awk '{print $7}' | awk -F"/" '{print $1}')
 
if [ $? -eq 0 ]; then
    echo "process id: $PID"
else
    echo "process process not exist"
    exit
fi
 
kill -9 ${PID}
 
if [ $? -eq 0 ]; then
    echo "kill $port success"
else
    echo "kill $port fail"
fi
done

9、验证

随便找个节点进入

./src/redis-cli -c -p 1101

127.0.0.1:1101> auth 123456
OK

# 查看集群状态
127.0.0.1:1101> cluster info

# 查看集群节点
127.0.0.1:1101> cluster nodes

3、springboot 服务

1、配置mysql读写分离和redis 集群

spring:
  shardingsphere:
    datasource:
      names: master,slave
      master:
        # 数据库连接池类名称
        type: com.zaxxer.hikari.HikariDataSource
        # 数据库驱动类名
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://xxxx:3306/service?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
        username: root
        password: root
      slave:
        # 数据库连接池类名称
        type: com.zaxxer.hikari.HikariDataSource
        # 数据库驱动类名
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://xxxx:3306/service?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
        username: root
        password: root
    # 规则配置
    rules:
      readwrite-splitting:
        load-balancers:
          ms:
            type: ROUND_ROBIN
            props:
              workId: 1
        data-sources:
          ms:
            type: Static
            load-balancer-name: round-robin
            props:
              write-data-source-name: master
              read-data-source-names: slave
    # 属性配置
    props:
      # 展示修改以后的sql语句
      sql-show: false
  redis:
    password: 123456 # Redis 服务器连接密码(默认为空)
    timeout: 3000ms # 连接超时时间(毫秒)
    jedis:
      pool:
        max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
        max-idle: 8 # 连接池中的最大空闲连接
        min-idle: 0 # 连接池中的最小空闲连接
        max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
    cluster:
      nodes: # Redis 集群节点地址和端口
        - 192.168.0.200:1101
        - 192.168.0.200:1102
        - 192.168.0.201:1101
        - 192.168.0.201:1102
        - 192.168.0.202:1101
        - 192.168.0.202:1102

2、读写分离事物配置


@Configuration
public class MasterDataSourceConfig {

    @Primary
    @Bean("masterSource")
    @ConfigurationProperties(prefix = "spring.shardingsphere.datasource.master")
    public DataSource dataSource() {
        return new HikariDataSource();
    }

    @Primary
    @Bean("masterTM")
    public DataSourceTransactionManager transactionManager(@Qualifier("masterSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

}

3、 修改事务注解 @Transactional(value = “masterTM”)

    @Override
    @Transactional(value = "masterTM")
    public void saveUserRole(SysUser user) {
        user.setCreateTime(new Date());
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        sysUserMapper.insert(user);
        sysUserRoleMapper.delete(Wrappers.<SysUserRole>update().lambda().eq(SysUserRole::getUserId, user.getUserId()));
        //保存用户与角色关系
        saveUserRoleList(user);
    }

最后

在每台机器分别启动服务即可,在nginx upstream 中修改对应ip 端口

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springboot + 读写分离+redis集群+集群部署 的相关文章

  • redis 2.8.7 Linux Sentinel环境配置问题,如何使其自启动,应该订阅什么?

    现在我们尝试使用 redis 2 8 7 作为缓存存储 来自使用 booksleeve 客户端的 NET Web 应用程序 目前看来这是一个非常有趣和令人兴奋的任务 redis 文档非常好 但由于缺乏真正的实践经验 我确实有几个关于如何正确
  • Scala 使用的 Redis 客户端库建议

    我正在计划使用 Scala 中的 Redis 实例进行一些工作 并正在寻找有关使用哪些客户端库的建议 理想情况下 如果存在一个好的库 我希望有一个为 Scala 而不是 Java 设计的库 但如果现在这是更好的方法 那么仅使用 Java 客
  • 使用redis进行树形数据结构

    我需要为基于树的键值开发一个缓存系统 与Windows注册表编辑器非常相似 其中缓存键是字符串 表示树中到值的路径 可以是原始类型 int string bool double 等 或子树本身 例如 key root x y z w val
  • Laravel Redis 配置

    我目前正在使用 Laravel 和 Redis 创建一个应用程序 几乎一切都工作正常 我按照文档中的说明扩展了身份验证 用户可以订阅 登录 注销 我可以创建内容 所有内容都存储在 Redis 中 但我有一个问题 我无法运行 php arti
  • Redis 在键过期时更新排序集

    我有一个 Redis 服务器 其中包含一组键值对和一个排序集 提供这些键值对的键的索引 键值对可以进入 已完成 状态 此时需要在 1 小时后删除它们 这可以通过在键上设置到期时间来简单地实现 但从排序集中清除它们似乎更成问题 我可以有一个过
  • Redis 是否使用用户名进行身份验证?

    我已经在我的环境中设置了Redis 并且只看到了通过密码授权的部分 有没有办法也设置用户名 还是只能通过密码验证 Redis 6 上有 ACL 这些都有一个用户名 查看https redis io topics acl https redi
  • 检查 Redis 列表中是否已存在某个值

    我想知道是否有办法检查 redis 列表中是否已存在某个键 我无法使用集合 因为我不想强制唯一性 但我确实希望能够检查字符串是否确实存在 Thanks 您的选择如下 Using LREM如果发现则更换它 维护一个单独的SET与您的LIST
  • JedisPoolConfig 不可分配给 GenericObjectPoolConfig

    我有一个基于 Spring 的 Java Web 应用程序托管在 Heroku 上 我正在尝试使用 Redis 实现来利用 Spring 缓存抽象 当服务器启动时 我收到一条错误消息 Type redis clients jedis Jed
  • 在 Redis 中存储 IP 范围

    我有很多不同提供商的 IP 范围 例如 P1 192 168 1 10 192 168 1 50 192 168 2 16 192 168 2 49 P2 17 36 15 34 17 36 15 255 P3 我将此 IP 转换为 int
  • 具有匹配模式的 ioredis 密钥

    我想用键匹配模式 LOGIN 搜索 Redis 数据库 我在我的应用程序中使用 ioredis 昨天我搜索了整个网络 我得到了一些执行这项工作的选项 如下所示 KEYS 扫描流 Issue import Redis from ioredis
  • 为什么Redis SET性能优于GET?

    根据Redis基准 http redis io topics benchmarkss Redis 可以执行 100 000 SET 操作 秒和 80 000 GET 操作 秒 Redis 是一种内存数据库 这似乎令人惊讶 因为通常人们会认为
  • 如何暂停或恢复 celery 任务?

    我的项目中有一项要求 客户可以暂停或恢复正在挂起的流程 而不是流程流程 我在用网络套接字显示芹菜任务结果 但在暂停 恢复时我不明白如何设计代码 我想到的唯一方法就是revoke暂停请求中的任务 同时保留数据撤销的过程在缓存中 并稍后在res
  • Flask-SocketIO redis 订阅

    我在用着https github com miguelgrinberg Flask SocketIO https github com miguelgrinberg Flask SocketIO实现 WebSocket 服务器 我需要从另一
  • 如果 Redis 已经是堆栈的一部分,为什么 Memcached 仍然与 Redis 一起使用?

    Redis 可以执行 Memcached 提供的所有操作 LRU 缓存 项目过期以及现在版本 3 x 中的集群 目前处于测试阶段 或通过 twemproxy 等工具执行 性能也类似 此外 Redis 增加了持久性 因此您无需在服务器重新启动
  • Redis 会话序列化器 3.2 和 4.2 之间不匹配

    我有一个基于 Spring Cloud 的应用程序在多个 spring boot 服务器上运行 所有服务器使用 EnableRedisHttpSession共享相同的Spring Session 我现在想将第三方小部件集成到我的应用程序中
  • 有没有办法在jedis中传递redis命令,而不使用函数?

    我们正在尝试构建一个控制台来处理 Redis 查询 但是 在后端我们需要使用Jedis 因此 作为输入给出的命令需要使用 Jedis 进行处理 例如 在redis cli中 我们使用 keys 同样 我们在 Jedis 中使用 jedis
  • 如何从redis中的哈希中获取与特定模式匹配的所有键?

    我想从哈希中获取所有键及其值 其中键与特定模式匹配 我将 Redis 与 C 库 ServiceStack Redis 结合使用 我找到了命令Keys with a pattern http redis io commands keys h
  • 在 Google App Engine Flex 上将 Websockets 与 Django 结合使用

    我目前正在尝试使用 django 框架和 django channels 设置 Google 应用程序引擎 Flex 对于我当前的项目 我需要一个 websocket 所以我尝试重建 Django channels 网站上提供的教程 htt
  • Sidekiq 不处理队列

    有哪些可能的原因可以Sidekiq https github com mperham sidekiq阻止处理队列中的作业 队列已满 日志文件sidekiq log表示根本没有活动 因此队列已满但日志为空 并且 Sidekiq 似乎没有处理项
  • 错误:Redis 连接到 127.0.0.1:6379 失败 - 连接 ECONNREFUSED 127.0.0.1:6379

    我试图允许我的nodeJs docker 映像与我的redis docker 映像 Mac OS X 环境 之间进行通信 NodeJs Dockerfile FROM node 4 7 0 slim EXPOSE 8100 COPY nod

随机推荐