I betragtning af populariteten af vores indlæg om at forbinde MongoDB SSL med selvsignerede certifikater i Node.js, besluttede vi at skrive et selvstudie om at forbinde MongoDB med Ruby. I denne blog viser vi dig, hvordan du opretter forbindelse til en MongoDB-server, der er konfigureret med selvsignerede certifikater til SSL ved hjælp af både Ruby MongoDB-driveren og den populære Object-Document-Mapper (ODM)-mongoid.
ScaleGrid bruger i øjeblikket selvsignerede certifikater til SSL ved oprettelse af noder til en ny klynge. Derudover giver vi dig også mulighed for at købe dine egne SSL-certifikater og konfigurere dem på MongoDB-serveren, og du kan sende en e-mail til [email protected] for at lære mere om dette tilbud.
Tilslutning til et replikasæt ved hjælp af Ruby MongoDB-driver
Vi vil bruge den seneste stabile Ruby MongoDB-driverversion 2.8 til dette eksempel. 2.5.x-versionerne af driveren har en kendt fejl, der forhindrer dem i at arbejde med ScaleGrid-implementeringer. Ruby-versionen, der bruges i begge eksempler nedenfor, er 2.6.3.
De tilgængelige forbindelsesmuligheder for driveren er dokumenteret her, og de muligheder, vi skal bruge, er:
- :ssl
- :ssl_verify
- :ssl_ca_cert .
Find og kopier først din MongoDB-forbindelsesstreng fra siden med klyngedetaljer på ScaleGrid-konsollen:
CA-certifikatfilen kan også downloades fra siden med klyngedetaljer. Download og gem certifikatfilen på et sted, der er tilgængeligt for applikationen:
Her er et uddrag, der viser, hvordan man opretter forbindelse til et MongoDB-repliksæt fra Ruby:
require 'mongo'Mongo::Logger.logger.level =::Logger::DEBUGMONGODB_CA_CERT ="/path/to/ca_cert.pem"MONGODB_CONN_URL ="mongodb://testuser:@SG-example- 17026.servers.mongodirector.com:27017,SG-example-17027.servers.mongodirector.com:27017,SG-example-17028.servers.mongodirector.com:27017/test?replicaSet=RS-example-0&ss" options ={ ssl:true, ssl_verify:true, :ssl_ca_cert => MONGODB_CA_CERT }client =Mongo::Client.new(MONGODB_CONN_URL, options)db =client.databasecollections =db.collection_namesputs "db #{db.name} has collections #name} {collections}"client.close
For at holde eksemplet simpelt har vi specificeret forbindelsesstrengen og certfilstien direkte i kodestykket – du ville normalt enten lægge dem i en yaml-fil eller angive dem som miljøvariabler. Eksemplet sætter også logniveauet til DEBUG
så eventuelle forbindelsesproblemer kan fejlsøges. Det bør ændres til et mindre udførligt niveau, når forbindelsesproblemer er blevet løst.
Sådan forbinder du MongoDB til en Ruby-applikation med SSLClick To Tweet
Opretter forbindelse ved hjælp af Mongoid
Den mongoid-version, vi vil bruge i vores eksempel, er den seneste stabile version – 7.0.2. Vi vil bruge en yaml-fil til at give konfiguration til mongoid, og detaljerne for en sådan konfigurationsfil er dokumenteret her. De SSL-specifikke konfigurationsmuligheder, vi skal bruge for at oprette forbindelse til vores replikasæt, er:
- ssl
- ssl_verify
- ssl_ca_cert
Vores yml-fil:
Eksempel på forbindelse:
gem 'mongoid', '7.0.2'require 'mongoid'Mongoid.load!("/path/to/mongoid.yml", :development)# Bruger ikke nogen af ODM-funktionerne - bare hent den underliggende mongo klient og forsøg på at forbinde klient =Mongoid::Clients.defaultdb =client.databasecollections =db.collection_namesputs "db #{db.name} har samlinger #{collections}"Mongoid::Clients.disconnect
Igen, i produktions Ruby on Rails-applikationer, ville yaml-filstien blive hentet fra miljøvariablerne.
Test af failover-adfærd
Ligesom andre MongoDB-drivere er Ruby MongoDB-driveren også designet til internt at genkende ændringer i topologi på grund af hændelser som failover. Det er dog godt at teste og validere driverens adfærd under failovers for at undgå overraskelser i produktionen.
Ligesom mit tidligere indlæg på MongoDB PyMongo kan vi skrive et evigt forfattertestprogram for at observere driverens failover-adfærd.
Den nemmeste måde at fremkalde failover på er at køre kommandoen rs.stepDown():
RS-example-0:PRIMARY> rs.stepDown()2019-04-18T19:44:42.257+0530 E QUERY [thread1] Fejl:fejl ved at udføre forespørgsel:mislykkedes:netværksfejl under forsøg på at køre kommandoen 'replSetStepDown' på vært 'SG-example-1.servers.mongodirector.com:27017' :DB.prototype.runCommand@src/mongo/shell/db.js:168:1DB.prototype.adminCommand@src/mongo/shell/db. js:185:1rs.stepDown@src/mongo/shell/utils.js:1305:12@(shell):1:12019-04-18T19:44:42.261+0530 I NETVÆRK [thread1] prøver at oprette forbindelse til SG-eksempel igen -1.servers.mongodirector.com:27017 (X.X.X.X) failed2019-04-18T19:44:43.267+0530 JEG NETVÆRK [thread1] genopretter forbindelse til SG-example-1.servers.mongodirector.com:27017 (X.) ok.eks. 0:SEKUNDÆR>
Her er de relevante dele af vores testkode:
require 'mongo'...logger =Logger.new(STDOUT)logger.level =Logger::INFOMONGODB_CA_CERT ="/path/to/ca_cert.pem"MONGODB_CONN_URL ="mongodb://testuser:@ SG-example-17026.servers.mongodirector.com:27017,SG-example-17027.servers.mongodirector.com:27017,SG-example-17028.servers.mongodirector.com:27017/test?replicaSet=RS-example 0&ssl=true"options ={ ssl:true, ssl_verify:true, :ssl_ca_cert => MONGODB_CA_CERT }begynd logger.info("Forsøg på at oprette forbindelse...") client =Mongo::Client.new(MONGODB_CONN_URL, optioner) i =0 loop do db =client.database collection =db[:test] start doc ={"idx":i, "date":DateTime.now, "text":SecureRandom.base64(3) } result =collection.insert_one( doc) logger.info("Record inserted - id:#{result.inserted_id}") i +=1 sleep(3) rescue Mongo::Error => e logger.error("Mong Error set:#{e.message }") logger.error(e.backtrace) logger.i nfo("Prøver igen...") end end logger.info("Done")rescue => err logger.error("Undtagelse set:#{err.message}") logger.error(err.backtrace)ensure client. luk, medmindre client.nil?end
Dette skriver løbende poster som disse til testsamlingen på testdatabasen:
RS-test-0:PRIMARY> db.test.find(){ "_id" :ObjectId("5cf50ff1896cd172a4f7c6ee"), "idx" :0, "date" :ISODate("2019-06-03T12:17 :53.008Z"), "text" :"HTvd" }{ "_id" :ObjectId("5cf50ff6896cd172a4f7c6ef"), "idx" :1, "date" :ISODate("2019-06-03T12:697:58". ), "text" :"/e5Z" }{ "_id" :ObjectId("5cf50ff9896cd172a4f7c6f0"), "idx" :2, "date" :ISODate("2019-06-03T12:18:01.940Z"), " text" :"quuw" }{ "_id" :ObjectId("5cf50ffd896cd172a4f7c6f1"), "idx" :3, "date" :ISODate("2019-06-03T12:18:05.194Z"), "tekst" :" gTyY" }{ "_id" :ObjectId("5cf51000896cd172a4f7c6f2"), "idx" :4, "date" :ISODate("2019-06-03T12:18:08.442Z"), "text" :"VDXX" "_id" :ObjectId("5cf51003896cd172a4f7c6f3"), "idx" :5, "date" :ISODate("2019-06-03T12:18:11.691Z"), "text" :"UY87" }... før>Lad os se adfærden under en failover:
I, [2019-06-03T17:53:25.079829 #9464] INFO -- :Forsøg på at oprette forbindelse...I, [2019-06-03T17:53:30.577099 #9464] INFO -- :Record indsat - ID:5CF5113F896CD124F8F31062I, [2019-06-03T17:53:33.816528 #9464] INFO-:Record Instented-ID:5CF51145896CD124F8F31063I, [2019-06-03T17:537.024744244242424242424242424242424424424424424424424424424242424242424242424242424242424242424242424242444 5cf51148896cd124f8f31064I, [2019-06-03T17:53:40.281537 #9464] INFO -- :Record inserted - id:5cf5114c896cd124f8f31065I, [2019-06-03T17:53:43.520010 #9464] INFO -- :Record inserted - id:5cf5114f896cd124f8f31066I, [2019-06-03T17:53:46.747080 #9464] Info-:Record Insterated-ID:5CF51152896CD124F8F31067i, [2019-06-03T17:53:49.978077 #9464] Info-:posten indsat-Id:5cf51111115111111111111111111111111111111111111111111111111111111111111111111 Failover påbegyndt herE, [2019-06-03T17:53:52.980434 #9464] FEJL -- :Mong Fejl set:EOFError:slutningen af filen nået (for x.x.x.x:27017 (sg-example-17026.directorservers.com:2go70directorservers.com:2go70directorservers. , TLS))E, [2019-06-03T17:53:52.980533 #9464] FEJL -- :["C:/Ruby 26-x64/lib/ruby/gems/2.6.0/gems/mongo-2.8.0/lib/mongo/socket.rb:300:in `rescue in handle_errors'", "C:/Ruby26-x64/lib/ ruby/gems/2.6.0/gems/mongo-2.8.0/lib/mongo/socket.rb:294:in `handle_errors'", "C:/Ruby26-x64/lib/ruby/gems/2.6.0/ gems/mongo-2.8.0/lib/mongo/socket.rb:126:in `read'", "C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/mongo-2.8.0/ lib/mongo/protocol/message.rb:139:in `deserialize'",......I, [2019-06-03T17:53:52.980688 #9464] INFO -- :Prøver igen...W, [ 2019-06-03T17:53:52.981575 #9464] ADVARSEL -- :Prøver ismaster igen på sg-example-17026.servers.mongodirector.com:27017 på grund af:Mongo::Error::SocketError EOFError nået (for end of file x.x.x.x:27017 (sg-example-17026.servers.mongodirector.com:27017, TLS))I, [2019-06-03T17:54:06.293100 #9464] INFO -- :Record indsat - 5916cf id:5916cf 59116cf 5116cf 59116cf 06-03T17:54:09.547716 #9464] INFO -- :Optegnelse indsat - id:5cf51169896cd124f8f3106bI, [2019-06-03T17:54:12.8046636] INERf 6c:1cd 6cd 6d 1cd 6d 1cd 6d 1cd 1cf 1cf 6cd 6cf 1cd 2019. re>Det er tydeligt, at hvis korrekte fejl fanges og læse/skrive forsøges igen, vil driveren automatisk registrere topologiændringen og genoprette forbindelse til den nye master. For skrivninger, muligheden :retry_writes sørg for, at driveren vil prøve igen én gang af sig selv, før han giver besked om en fejl.
Der er også flere driver-timeouts, der kan justeres baseret på den nøjagtige adfærd og forsinkelse, du ser på din opsætning. Disse er dokumenteret her.
Fejlfinding
Hvis du har problemer med at oprette forbindelse til din SSL-aktiverede MongoDB-implementering, er her et par tip til fejlretning:
- Først skal du kontrollere, at du faktisk kan oprette forbindelse til MongoDB-serveren fra serveren, hvor din applikation kører. Den nemmeste måde at gøre dette på er at installere mongo shell på klientmaskinen. På Linux behøver du ikke installere hele MongoDB-serveren - du kan vælge bare at installere skallen separat. Når shellen er tilgængelig, kan du prøve at bruge den 'Kommandolinjesyntaks', vi leverer, til at forsøge at oprette forbindelse til serveren.
- Hvis du ikke er i stand til at oprette forbindelse via mongo-skallen, betyder det, at klientmaskinen ikke er i stand til at nå port 27017 på MongoDB-serverne. Se på dine sikkerhedsgruppe-, VPC- og ScaleGrid-firewallindstillinger for at sikre, at der er forbindelse mellem klient- og servermaskinerne.
- Hvis netværksforbindelsen er korrekt, er den næste ting at kontrollere, at du bruger versioner af Ruby, mongoid og mongo gem, der er kompatible med versionen af din MongoDB-server.
- Hvis du har bekræftet, at driverversionerne er korrekte, kan du prøve at køre et eksempel på Ruby-script, svarende til eksemplet, vi har givet ovenfor, på IRB'en. En trin-for-trin udførelse kan pege på, hvor problemet er.
- Hvis testscriptet kører fint, men du stadig ikke er i stand til at oprette forbindelse til mongoid, så prøv at køre et simpelt testscript, som eksemplet ovenfor. .
- Hvis du stadig har problemer med at oprette forbindelse til din instans, bedes du skrive til os på [email protected] med detaljerede resultater af ovenstående fejlfindingstrin og med de nøjagtige versioner af Ruby, mongoid og mongo driver du bruger. Gemfile.lock vil give dig de nøjagtige versioner.
Hvis du er ny i ScaleGrid og vil prøve denne tutorial, kan du tilmelde dig en gratis 30-dages prøveperiode for at udforske platformen og afprøve platformen forbinder MongoDB til din Ruby-applikation.