Connection timeout to MongoDb on Azure VM

2019-05-11 00:39发布

问题:

I have some timeout problems when connecting my Azure Web App to a MongoDb hosted on a Azure VM.

2015-12-19T15:57:47.330+0100 I NETWORK  Socket recv() errno:10060 A connection attempt 
 failed because the connected party did not properly respond after a period of time, 
 or established connection failed because connected host has failed to respond.
2015-12-19T15:57:47.343+0100 I NETWORK  SocketException: remote: 104.45.x.x:27017 error: 
 9001 socket exception [RECV_ERROR] server [104.45.x.x:27017]
2015-12-19T15:57:47.350+0100 I NETWORK  DBClientCursor::init call() failed

Currently mongodb is configured on a single server (just for dev) and it is exposed through a public ip. Website connect to it using an azure domain name (*.westeurope.cloudapp.azure.com) and without a Virtual Network.

Usually everything works well, but after some minutes of inactivity I get that timeout exception. The same will happen when using the MongoDb shell from my PC, so I'm quite sure that it is a problem on mongodb side.

I'm missing some configuration?

回答1:

After some searching here my considerations:

  • It is usually a good practice to implement some sort of retry logic on every resource that you access on Azure (database, VM, ...). For MongoDb there is a partial implementation so you should potentially write your own. See also this issue and this.
  • If possible all resources on Azure should be in the same Azure Virtual Network (in this way all connections are made using Azure Private Ip instead of Public Ip. This is also useful for security reasons because you don't need to open endpoint to the public.
  • When deploying MongoDb on Azure try to follow the official MongoDb guidelines.
  • In this particular case you should set the net.ipv4.tcp_keepalive_time to a value lower than the tcp keep alive of Azure, that by default is 240 seconds. In this way the connection is closed and MongoDb driver can intercept this condition and open a new connection. If the connection is closed by Azure the driver cannot intercept it. If you want to change this setting on Azure (not recommended) you can find it inside the Public Ip configuration.

In my development environment I have set the net.ipv4.tcp_keepalive_time to 120 and now everything seems to work fine. Consider that if you host MondoDb inside an Docker container you should set this setting on the Docker host.

Here some other useful links:

  • http://focusmatic.tumblr.com/post/39569711018/solving-mongodb-connection-losses-on-windows-azure
  • https://docs.mongodb.org/ecosystem/platforms/windows-azure/
  • https://michaelmckeownblog.wordpress.com/2013/12/04/resolving-internal-ips-vs-dns-names-between-vms/
  • https://gist.github.com/davideicardi/f2094c4c3f3e00fbd490
  • MongoDB connection problems on Azure
  • MongoDB connection timeouts (Azure)


回答2:

When using the C# Mongo driver we resolved this by setting the following

MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);