Gezien de populariteit van ons bericht over het verbinden van MongoDB SSL met zelfondertekende certificaten in Node.js, hebben we besloten een tutorial te schrijven over het verbinden van MongoDB met Ruby. In deze blog laten we u zien hoe u verbinding kunt maken met een MongoDB-server die is geconfigureerd met zelfondertekende certificaten voor SSL met behulp van zowel het Ruby MongoDB-stuurprogramma als de populaire Object-Document-Mapper (ODM) mongoid.
ScaleGrid gebruikt momenteel zelfondertekende certificaten voor SSL bij het maken van nodes voor een nieuw cluster. Daarnaast bieden we u ook de mogelijkheid om uw eigen SSL-certificaten aan te schaffen en deze te configureren op de MongoDB-server, en u kunt een e-mail sturen naar [email protected] voor meer informatie over deze aanbieding.
Verbinding maken met een replicaset met Ruby MongoDB-stuurprogramma
We zullen voor dit voorbeeld de nieuwste stabiele Ruby MongoDB-stuurprogrammaversie 2.8 gebruiken. De 2.5.x-versies van het stuurprogramma hebben een bekende bug waardoor ze niet kunnen werken met ScaleGrid-implementaties. De Ruby-versie die in beide onderstaande voorbeelden wordt gebruikt, is 2.6.3.
De beschikbare verbindingsopties voor het stuurprogramma worden hier beschreven, en de opties die we nodig hebben zijn:
- :ssl
- :ssl_verify
- :ssl_ca_cert .
Zoek en kopieer eerst uw MongoDB-verbindingsreeks vanaf de pagina met clusterdetails op de ScaleGrid-console:
Het CA-certificaatbestand kan ook worden gedownload vanaf de pagina met clusterdetails. Download en bewaar het cert-bestand op een locatie die beschikbaar is voor de applicatie:
Hier is een fragment dat laat zien hoe u verbinding kunt maken met een MongoDB-replicaset van 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&ssl=true" 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} heeft collectie {collections}"client.close
Om het voorbeeld eenvoudig te houden, hebben we de verbindingsreeks en het cert-bestandspad direct in het codefragment gespecificeerd - u zou ze over het algemeen ofwel in een yaml-bestand plaatsen of ze specificeren als omgevingsvariabelen. Ook stelt het voorbeeld het logniveau in op DEBUG
zodat eventuele verbindingsproblemen kunnen worden opgespoord. Het moet worden gewijzigd in een minder uitgebreid niveau zodra de verbindingsproblemen zijn opgelost.
MongoDB verbinden met een Ruby-applicatie met SSLClick To Tweet
Verbinding maken met Mongoid
De mongoïde versie die we in ons voorbeeld zullen gebruiken, is de nieuwste stabiele versie – 7.0.2. We zullen een yaml-bestand gebruiken om de mongoïde configuratie te geven, en de details van zo'n configuratiebestand worden hier gedocumenteerd. De SSL-specifieke configuratie-opties die we nodig hebben om verbinding te maken met onze replicaset zijn:
- ssl
- ssl_verify
- ssl_ca_cert
Ons yml-bestand:
ontwikkeling:# Configureer beschikbare databaseclients. (verplichte) clients:# Definieer de standaard client. (vereist) standaard:# Er kan een uri worden gedefinieerd voor een client:# uri:'mongodb://user:[email protected]:27017/my_db' # Zie de driverdocumentatie voor details. U kunt ook het volgende definiëren:# # Definieer de naam van de standaarddatabase waarmee Mongoid verbinding kan maken. # (vereist). database:test # Geef de hosts op waarmee de standaardclient verbinding kan maken. Moet een array # van host:port-paren zijn. (vereist) hosts:- SG-example-17026.servers.mongodirector.com:27017 - SG-example-17027.servers.mongodirector.com:27017 - SG-example-17028.servers.mongodirector.com:47100 opties:# De naam van de gebruiker voor authenticatie. gebruiker:'testgebruiker' # Het wachtwoord van de gebruiker voor authenticatie. wachtwoord:'pwd' # De databaserollen van de gebruiker. rollen:- 'readWrite' # Wijzig het standaard authenticatiemechanisme. Geldige opties zijn::scram, # :mongodb_cr, :mongodb_x509 en :plain. (standaard op 3.0 is :scram, standaard # op 2.4 en 2.6 is :plain) auth_mech::scram # De database of bron voor authenticatie van de gebruiker. (standaard:admin) auth_source:test # Forceer het stuurprogramma om op een specifieke manier verbinding te maken in plaats van # automatisch te ontdekken. Kan een van de volgende zijn::direct, :replica_set, :sharded. Stel in op :direct # wanneer u verbinding maakt met verborgen leden van een replicaset. connect::replica_set ... ... # De naam van de replicaset waarmee verbinding moet worden gemaakt. Servers die als seed worden geleverd en die # niet bij deze replicaset horen, worden genegeerd. replica_set:RS-voorbeeld-0 # Of u verbinding wilt maken met de servers via ssl. (standaard:false) ssl:true # Wel of niet peer-certificering valideren. (standaard:waar) ssl_verify:waar # Het bestand met een reeks aaneengeschakelde certificeringen van de certificeringsinstantie # dat wordt gebruikt om certificaten te valideren die aan de andere kant van de verbinding zijn doorgegeven. ssl_ca_cert:/path/to/ca_cert.pem # Configureer Mongoid-specifieke opties. (optioneel) opties:# Stel de logniveaus van de Mongoid- en Ruby-stuurprogramma's in. (standaard::info) log_level::debug
Verbindingsvoorbeeld:
gem 'mongoid', '7.0.2'require 'mongoid'Mongoid.load!("/path/to/mongoid.yml", :development)# Geen van de ODM-functies gebruiken - haal gewoon de onderliggende mongo op client en probeer verbinding te makenclient =Mongoid::Clients.defaultdb =client.databasecollections =db.collection_namesputs "db #{db.name} has collections #{collections}"Mongoid::Clients.disconnect
Nogmaals, in productie Ruby on Rails-toepassingen zou het yaml-bestandspad worden opgehaald uit de omgevingsvariabelen.
Failover-gedrag testen
Net als andere MongoDB-stuurprogramma's, is het Ruby MongoDB-stuurprogramma ook ontworpen om intern wijzigingen in de topologie te herkennen als gevolg van gebeurtenissen zoals failover. Het is echter goed om het gedrag van de bestuurder tijdens failovers te testen en te valideren om verrassingen in de productie te voorkomen.
Net als mijn vorige post op MongoDB PyMongo, kunnen we een eeuwigdurend schrijver-testprogramma schrijven om het failover-gedrag van de driver te observeren.
De gemakkelijkste manier om een failover te induceren is door de opdracht rs.stepDown() uit te voeren:
RS-example-0:PRIMARY> rs.stepDown()2019-04-18T19:44:42.257+0530 E QUERY [thread1] Fout:fout bij uitvoeren van query:mislukt:netwerkfout tijdens poging om opdracht 'replSetStepDown' uit te voeren op host '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 NETWORK [thread1] probeer opnieuw verbinding te maken met SG-voorbeeld -1.servers.mongodirector.com:27017 (X.X.X.X) mislukt2019-04-18T19:44:43.267+0530 I NETWORK [thread1] maak opnieuw verbinding met SG-example-1.servers.mongodirector.com:27017 (X.X.X.X) okRS-example- 0:SECUNDAIR>
Dit zijn de relevante delen van onze testcode:
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 }begin logger.info("Poging om verbinding te maken...") client =Mongo::Client.new(MONGODB_CONN_URL, opties) i =0 loop do db =client.database collection =db[:test] begin doc ={"idx":i, "date":DateTime.now, "text":SecureRandom.base64(3) } result =collection.insert_one( doc) logger.info("Record ingevoegd - id:#{result.inserted_id}") i +=1 sleep(3) rescue Mongo::Error => e logger.error("Mong Fout gezien:#{e.message }") logger.error(e.backtrace) logger.i nfo("Opnieuw proberen...") end end logger.info("Klaar")rescue => err logger.error("Uitzondering gezien:#{err.message}") logger.error(err.backtrace)zorg ervoor dat de klant. sluiten tenzij client.nil?end
Dit schrijft continu items zoals deze naar de testverzameling in de testdatabase:
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:17:58.697Z" ), "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"), "text" :" 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" }...
Laten we eens kijken naar het gedrag tijdens een failover:
I, [2019-06-03T17:53:25.079829 #9464] INFO -- :Poging om verbinding te maken...I, [2019-06-03T17:53:30.577099 #9464] INFO -- :Record ingevoegd - id:5cf5113f896cd124f8f31062I, [2019-06-03T17:53:33.816528 #9464] INFO -- :Record ingevoegd - id:5cf51145896cd124f8f31063I, [2019-06-03T17:53:37.047043 #9464] INFO --::Record ingevoegd - id 5cf51148896cd124f8f31064I, [2019-06-03T17:53:40.281537 #9464] INFO -- :Record ingevoegd - id:5cf5114c896cd124f8f31065I, [2019-06-03T17:53:43.520010 #9464] INFO -- :Record ingevoegd - id:3106 [2019-06-03T17:53:46.747080 #9464] INFO -- :Record ingevoegd - id:5cf51152896cd124f8f31067I, [2019-06-03T17:53:49.978077 #9464] INFO -- :Record ingevoegd - id:5cf51155896cd124f8f31068 <<Het is duidelijk dat als de juiste fouten worden ontdekt en het lezen/schrijven opnieuw wordt geprobeerd, het stuurprogramma automatisch de topologiewijziging zal detecteren en opnieuw verbinding zal maken met de nieuwe master. Voor schrijven, de optie :retry_writes zorg ervoor dat de bestuurder het zelf een keer opnieuw probeert voordat hij de toepassing op de hoogte stelt van een fout.
Er zijn ook meerdere time-outs voor stuurprogramma's die kunnen worden aangepast op basis van het exacte gedrag en de exacte latentie die u in uw installatie ziet. Deze worden hier gedocumenteerd.
Problemen oplossen
Als je problemen hebt om verbinding te maken met je SSL-enabled MongoDB-implementatie, volgen hier een paar tips voor het opsporen van fouten:
- Controleer eerst of u daadwerkelijk verbinding kunt maken met de MongoDB-server vanaf de server waarop uw toepassing draait. De eenvoudigste manier om dit te doen, is door mongo-shell op de clientcomputer te installeren. Op Linux hoeft u niet de hele MongoDB-server te installeren - u kunt ervoor kiezen om de shell afzonderlijk te installeren. Zodra de shell beschikbaar is, probeert u de 'Command Line Syntax' die we bieden te gebruiken om te proberen verbinding te maken met de server.
- Als u geen verbinding kunt maken via de mongo-shell, betekent dit dat de clientcomputer poort 27017 van de MongoDB-servers niet kan bereiken. Kijk naar de firewall-instellingen van uw Security Group, VPC en ScaleGrid om er zeker van te zijn dat er verbinding is tussen de client- en servermachines.
- Als de netwerkverbinding correct is, is het volgende dat u moet controleren of u versies van Ruby, mongoid en mongo gem gebruikt die compatibel zijn met de versie van uw MongoDB-server.
- Als je hebt bevestigd dat de stuurprogrammaversies correct zijn, probeer dan een voorbeeld van een Ruby-script uit te voeren, vergelijkbaar met het voorbeeld dat we hierboven hebben gegeven, op de IRB. Een stapsgewijze uitvoering kan aangeven waar het probleem zit.
- Als het testscript goed werkt, maar je nog steeds geen verbinding kunt maken met mongoid, probeer dan een eenvoudig testscript uit te voeren, zoals het voorbeeld dat we hierboven hebben gegeven .
- Als u nog steeds problemen ondervindt bij het maken van verbinding met uw instantie, schrijf ons dan op [email protected] met gedetailleerde resultaten van de bovenstaande stappen voor probleemoplossing en met de exacte versies van Ruby, mongoid en mongo driver die u gebruikt. De Gemfile.lock geeft je de exacte versies.
Als u nieuw bent bij ScaleGrid en deze tutorial eens wilt proberen, meld u dan aan voor een gratis proefperiode van 30 dagen om het platform te verkennen en uit te testen MongoDB verbinden met uw Ruby-applicatie.