Máte po upgradu ovladače MongoDB Ruby na verzi 2.5.x potíže s připojením k sadám replik MongoDB? Nedávno jsme obdrželi několik dotazů ohledně tohoto problému s nejnovější verzí ovladače MongoDB Ruby a napsali jsme tento příspěvek, abychom se podělili o naše zjištění ohledně problému a příčiny.
Chybová zpráva, která se objevila při pokusu o připojení, byla -
No server is available matching preference: #<Mongo::ServerSelector::Primary:...>
Problém již byl nahlášen MongoDB a sleduje se zde. Strávili jsme nějaký čas zkoumáním tohoto problému a hlavní příčiny uvedené v kódu ovladače v 2.5.x.
Shrnutí problémů MongoDB Ruby Driver 2.5.x
Problém existuje ve verzi 2.5.x ovladače MongoDB Ruby a vyskytuje se, když názvy hostitelů tvořící sadu replik obsahují velká a malá písmena, např. ABC-server1.example.com . Možná řešení jsou:
- Přejděte na nižší verzi 2.4.x nebo upgradujte na verzi 2.6.x, jakmile bude k dispozici.
- Změňte názvy hostitelů všech členů sady replik na malá písmena. Například změňte název hostitele ve výše uvedeném příkladu na abc-server1.example.com.
Podrobnosti o problému
Povolení podrobného protokolování na Ruby poskytlo vodítko k tomu, co se děje:
... #19140] DEBUG -- : MONGODB | Topology type 'replica set' initializing. #19140] DEBUG -- : MONGODB | Server sg-connectiontest1-13622.servers.example.com:27017 initializing. #19140] DEBUG -- : MONGODB | Server description for sg-connectiontest1-2.servers.example.com:27017 changed from 'unknown' to 'unknown'. #19140] DEBUG -- : MONGODB | Server sg-connectiontest1-13623.servers.example.com:27017 initializing. #19140] DEBUG -- : MONGODB | Server description for sg-connectiontest1-3.servers.example.com:27017 changed from 'unknown' to 'secondary'. #19140] DEBUG -- : MONGODB | Server sg-connectiontest1-13624.servers.example.com:27017 initializing. #19140] DEBUG -- : MONGODB | Server description for sg-connectiontest1-4.servers.example.com:27017 changed from 'unknown' to 'arbiter'. #19140] DEBUG -- : MONGODB | There was a change in the members of the 'replica set' topology. C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/mongo-2.5.1/lib/mongo/server_selector/selectable.rb:119:in `select_server': No server is available matching preference: # using server_selection_timeout=30 and local_threshold=0.015 (Mongo::Error::NoServerAvailable) from lib/ruby/gems/2.4.0/gems/mongo-2.5.1/lib/mongo/database.rb:157:in `command' from lib/ruby/gems/2.4.0/gems/mongo-2.5.1/lib/mongo/client.rb:404:in `list_databases' from lib/ruby/gems/2.4.0/gems/mongo-2.5.1/lib/mongo/client.rb:385:in `database_names' ...
Zdálo se zřejmé, že ovladač nebyl schopen správně detekovat roli primárního prvku sady replik. Při porovnání s protokoly z 2.4.x bylo jasné, že se to v této verzi stávalo správně, tj. primární byl správně identifikován jako primární.
] DEBUG -- : MONGODB | Topology type 'replica set' initializing. ] DEBUG -- : MONGODB | Server sg-connectiontest1-13622.servers.example.com:27017 initializing. ] DEBUG -- : MONGODB | Server description for sg-connectiontest1-2.servers.example.com:27017 changed from 'unknown' to 'primary'. ] DEBUG -- : MONGODB | Server sg-connectiontest1-13623.servers.example.com:27017 initializing. ] DEBUG -- : MONGODB | Server description for sg-connectiontest1-3.servers.example.com:27017 changed from 'unknown' to 'secondary'. ] DEBUG -- : MONGODB | Server sg-connectiontest1-13624.servers.example.com:27017 initializing. ] DEBUG -- : MONGODB | Server description for sg-connectiontest1-4.servers.example.com:27017 changed from 'unknown' to 'arbiter'.
Dalším vodítkem, které jsme měli, bylo, že názvy našich serverů byly v protokolech mírně změněny. Místo skutečného názvu SG -test připojení1-2.servers.example.com , byl protokolován jako sg -test připojení1-2.servers.example.com .
Při kontrole kódu kolem toho, jak jsou názvy hostitelů analyzovány během inicializace připojení a jsou jim přiřazovány role, jsme byli schopni určit, že kód ovladače byla malá (tj. převod ABC. example.com na abc.example.com) při analýze připojovacího řetězce. Dále se ovladač připojí k primárnímu, aby zjistil topologii pomocí příkazu isMaster. Roli každého uzlu určuje ovladač při analýze výsledku tohoto příkazu.
MongoDB Ruby Driver 2.5.x Problémy s rozlišením malých a velkých písmen u názvů hostitelů v sadách replik Kliknutím na TweetPři porovnávání názvů hostitelů vrácených z příkazu s názvy v připojovacím řetězci však ovladač ignoroval, aby provedl shodu bez rozlišení velkých a malých písmen. To vedlo k neshodě v názvech primárního, jak je hlášeno MongoDB, s tím, co ovladač určil z připojovacího řetězce. To způsobilo, že role primárního se stala neznámou a vedlo k selhání připojení. Kontrola shody adresy v kódu detekce role byla přidána v 2.5.x.
Oprava problému byla zaměřena na verzi 2.6.0 ovladače.