prisma使用mongodb副本集群报错引发的一些列问题

本文详述了在使用Prisma与MongoDB副本集群配合时遇到的错误,问题在于Prisma在获取副本集信息时,发现配置中的host为localhost。通过检查并修改MongoDB副本集配置,确保所有host为非localhost地址,解决了该问题。文章还提供了Docker Compose部署MongoDB副本集群的示例,并分享了验证连接成功的步骤。
摘要由CSDN通过智能技术生成

prisma使用mongodb副本集群报错引发的一些列问题

  • 前提:因为prisma对于增删改有事务,所以必须使用mongdb副本集群

    • 详细参考官方:https://www.prisma.io/docs/concepts/database-connectors/mongodb#troubleshooting
  • 错误描述

    None of the available servers suitable for criteria Predicate. Topology: { Type: Unknown, Servers: [ { Address: localhost:27017, Type: RsGhost, Average RTT: 346.567µs, Last Update Time: DateTime(2022-02-16T20:00:59.552Z), Max Wire Version: 9, Min Wire Version: 0 }, ] }
    

    错误描述很清楚Address: localhost:27017,没有找到合适可用的服务

  • .env文件

    DATABASE_URL="mongodb://自己的云服务器ip地址:27018/test?authSource=admin&retryWrites=true&w=majority"
    
  • schema.prisma

    datasource db {
      provider = "mongodb"
      url      = env("DATABASE_URL")
    }
    
    generator client {
      provider        = "prisma-client-js"
    }
    

一切都很平平无奇,下面进行排查流程,此处不做如何搭建mongodb副本集群的教程,可以百度,上面有很多教程

思考1:db url字段

  • 很显然,我的肯定是没问题,用一些gui 可视化mongodb连接工具即可

思考2:mongodb副本集群host字段不能为localhost或127.0.0.1

  • 查看错误信息,如果是副本集群报错应该是多个数组(这里拿的是别人的错误,所以只有一个)

    Topology: { 
      Type: Unknown, 
        Servers: [ 
          { 
            Address: localhost:27017, 
            Type: RsGhost, 
            Average RTT: 346.567µs, 
            Last Update Time: DateTime(2022-02-16T20:00:59.552Z), 
          Max Wire Version: 9, 
          Min Wire Version: 0 
          }, 
       	] 
    }
    
  • 可以看到address字段为localhost:port形式,那么,会不会因为prisma会向mongodb副本集群获取rs.config()然后再根据配置的host进行连接?

  • 这里直接告诉结论:是的,prisma就是这样做的

    1. 首先查看自己的配置信息,进入mongo/mongosh,rs.config()可以发现你配置的所有副本集群信息

    2. host: localhost进行修改

      // 进入主机节点,比如27017是主节点
      mongo/mongosh localhost:27017
      
      config = rs.config();
      // 打印config信息
      members: [
        {
          _id: 1,
          host: 'localhost:27017',
          arbiterOnly: false,
          buildIndexes: true,
          hidden: false,
          priority: 1,
          tags: {},
          secondaryDelaySecs: Long("0"),
          votes: 1
        },
        {
          _id: 2,
          host: 'localhost:27018',
          arbiterOnly: false,
          buildIndexes: true,
          hidden: false,
          priority: 1,
          tags: {},
          secondaryDelaySecs: Long("0"),
          votes: 1
        }
      ],
      
      // 因为使用了对host都是localhost, 所以直接修改配置文件会报错:Either all host names in a replica set configuration must be localhost references, or none must be; found 1 out of 2.
      // 意思就是,所有副本集的host配置要么是localhost要么都不是localhost
      // 移除副本节点
      rs.remove('loclhost:27018');
      
      // 修改配置
      reconfig = rs.config().members[0].host = 'ip:port'; // 要么修改成ip:端口,也可以用域名代替
      rs.reconfig(reconfig);
      
      // 查看是否修改成功
      rs.config();
      
      // 添加子节点
      rs.add('ip:port'); // 或域名:端口
      
      // 查看是否修改成功
      rs.config();
      // 查看状态
      rs.status();
      
  • 最后验证

    1. npx prisma studio:进去后不报错就是ok

    2. 跑一个查询代码

      import { PrismaClient } from '@prisma/client';
      const prisma = new PrismaClient();
      
      async function main() {
        await prisma.$connect();
        const allUsers = await prisma.user.findMany();
        console.log(allUsers);
      }
      
      main()
        .catch((e) => {
          console.log(e);
        })
        .finally(async () => {
          await prisma.$disconnect();
        });
      
      

      结果不管怎样,只要没报错就是ok的

使用docker-compose部署

贴上一个简单实用keyFile集群成员认证 + 客户端账号密码认证的1主2从副本集群攻略

日期:2022-07-31

  • 运行之前需要生成一个KeyFile
openssl rand -base64 756 > /data/mongodb.key
  • docker-compose文件

    version: '3.1'
    
    services:
      mongodb1:
      	# 默认最新
        image: mongo
        # 错误后自动重启
        restart: on-failure
        container_name: mongo1
        volumes:
        	# 数据存放目录
          - ./db/mongo1:/data/db
          # keyfile:用于集群之间的认证,⚠️ 注意调整你自己的路径
          - /data/mongodb/mongodb.key:/data/mongodb.key
          # 配置目录
          - ./config/mongo1:/data/configdb
        ports:
          - 27017:27017
        environment:
          MONGO_INITDB_ROOT_USERNAME: admin
          MONGO_INITDB_ROOT_PASSWORD: admin
        networks:
          - mongoNet
        command: mongod --replSet rs0 --keyFile /data/mongodb.key
        entrypoint: 
          - bash 
          - -c 
          - | 
            chmod 400 /data/mongodb.key 
            chown 999:999 /data/mongodb.key
            exec docker-entrypoint.sh $$@
    
            
    
      mongodb2:
        image: mongo
        restart: on-failure
        container_name: mongo2
        volumes:
          - ./db/mongo2:/data/db
          - /data/mongodb/mongodb.key:/data/mongodb.key
          - ./config/mongo2:/data/configdb
        ports:
          - 27018:27017
        environment:
          MONGO_INITDB_ROOT_USERNAME: admin
          MONGO_INITDB_ROOT_PASSWORD: admin
        networks:
          - mongoNet
        command: mongod --replSet rs0 --keyFile /data/mongodb.key
        entrypoint:
          - bash
          - -c
          - |
            chmod 400 /data/mongodb.key 
            chown 999:999 /data/mongodb.key
            exec docker-entrypoint.sh $$@
    
      mongodb3:
        image: mongo
        restart: on-failure
        container_name: mongo3
        volumes:
          - ./db/mongo3:/data/db
          - /data/mongodb/mongodb.key:/data/mongodb.key
          - ./config/mongo3:/data/configdb
        ports:
          - 27019:27017
        environment:
          MONGO_INITDB_ROOT_USERNAME: admin
          MONGO_INITDB_ROOT_PASSWORD: admin
        networks:
          - mongoNet
        command: mongod --replSet rs0 --keyFile /data/mongodb.key
        entrypoint:
          - bash
          - -c
          - |
            chmod 400 /data/mongodb.key 
            chown 999:999 /data/mongodb.key
            exec docker-entrypoint.sh $$@
        
    networks:
      mongoNet:
        driver: bridge
    
  • 进入节点:docker exec -it mongo1 /bin/bash

    rs.initiate({ 
      // 集群名称,一定要和配置文件保持一致
      _id: "rs0", 
      members: [ 
        // 一定要用公网,否则访问不到
        { _id: 0, host: "xxxxxxxx:port" }, 
        { _id: 1, host: "xxxxxxxx:port" }, 
        { _id: 2, host: "xxxxxxxx:port" }
      ] 
    });
    rs.status(); // 测试:查看集群状态
    
  • 测试,使用gui通过账号密码登陆测试

    // 我用的DataGrip(all in one 工具) 你可以用navicat、stdio 3T
    mongodb://admin:admin@xxx:port1,xxx:port2,xxx:port3/test?replicaSet=rs0&authSource=admin&slaveOk=true&connectTimeoutMS=5000
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值