Azure: Java 连接SQL Azure数据库及Connection timeout问题解决方法

来源:互联网 发布:哈佛学生知乎 编辑:程序博客网 时间:2024/04/29 16:55

SQL Azure是Azure提供的关系数据库服务,它天生支持高可用性,扩展性。使用SQL Azure,开发人员不需要自己安装,升级,维护服务器,只需要简单的在Azure portal上创建一个SQL Azure服务器实例即可。SQL Azure是基于SQL Server的,其实,它就是SQL Server的一个受限制版本。SQL Azure支持几乎我们会用到的所有SQL Server的数据类型,支持T-SQL。关于SQL Azure的限制可以参考http://msdn.microsoft.com/en-us/library/ff394115.aspx。 更多资料可以参考http://stackoverflow.com/questions/3235164/what-is-the-difference-between-sql-azure-and-sql-server-2008。

一,Web版和Business版

在Azure portal,我们先创建一个SQL Azure的服务器。之后在服务器上,我们就可以创建SQL Azure的数据库。SQL Azure数据库分为两个版本:Web版和Business版。目前为止,这两个版本只是微软提出的概念,可能将来Business版本会有比Web版更多的功能,但是现在来说,除了数据库的最大容量,这两个版本并没有任何区别。Web版最大只支持5G,而Business版可以支持150G。选择Web版或者Business版后,可以选择数据库的最大容量,根据自己的需求选择一个即可。事实上,不管你选择什么版本,什么容量,这些都是可以改变的,在运行过程中,通过SQL语句即可更改:

CREATE DATABASE Test (EDITION='WEB', MAXSIZE=1GB)ALTER DATABASE Test MODIFY (EDITION='WEB', MAXSIZE=5GB)ALTER DATABASE Test MODIFY (EDITION='BUSINESS', MAXSIZE=10GB)
例子中先创建了一个1G的Web版数据库,第二句把最大容量改成了5G,第三句把版本改成Business,容量改成10G。 如果觉得用不完这么多,再改回Web版也是可以的。参考: http://stackoverflow.com/questions/3426360/sql-azure-web-vs-business-edition


二,JDBC驱动

因为SQL Azure是SQL Server的一个子版本,所以驱动实用的和SQL Server也是一样的。Java 5的下载3.0驱动:http://www.microsoft.com/en-us/download/details.aspx?id=19847,Java 6或者7的下载4.0驱动:http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=11774。下载的exe文件安装后,在安装目录里可以找到sqljdbc.jar或者sqljdbc4.jar, 这个jar就是JDBC驱动。微软不支持Java 1.4,参考:http://msdn.microsoft.com/en-us/library/ms378422.aspx。


三,连接数据库

类com.microsoft.sqlserver.jdbc.SQLServerDriver是驱动的入口,配置驱动类为这个类,并把SQL Azure服务器的URL地址填好就可以了,下面是一个Grails里配置的例子:

dataSource.pooled=truedataSource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriverdataSource.username=username@servernamedataSource.password=userpassworddataSource.dbCreate=updatedataSource.url=jdbc:sqlserver://servername.database.windows.net:1433;database=databasename;ordataSource.url=jdbc:sqlserver://servername.database.windows.net:1433;database=databasename;encrypt=true;hostNameInCertificate=data.ch1-1.database.windows.net;
注:用户名要带上SQL Azure服务器的名字,用户名和密码单独配置后,就不需要在URL里再配置了。 数据库连接的URL要带上数据库的名字。例子中的URL第一个是普通连接,第二个是SSL加密的连接,hostNameInCertificate会因为SQL Azure服务器处在的位置不同而不同,如果填错了,会出excpetion,其中会带有正确的URL,填回来即可。

如果要自己创建连接当然也是可以的:

String connectionUrl = "jdbc:sqlserver://servername.database.windows.net;database=databasename;user=username@servername;password=userpassword";Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");Connection con = DriverManager.getConnection(connectionUrl);

四,数据库连接丢失问题

有两个问题会导致和SQL Azure的连接中断:

1.SQL Azure自带的网关会关闭连接。SQL Azure的网关会监视每一个连接,如果某个连接在30分钟内都没有进行过数据库操作(如查询,插入,创建表),SQL Azure就会把这个连接关闭。这个问题的最好解决方法是使用数据库连接池,并且连接池里的连接在丢失后要能够自动恢复。另外的方法就是对每个连接,定期去做些数据库操作,但是微软不推荐这样,因为会造成连接的浪费。

2. 和数据库的连接在TCP层面上,有可能被所经过的任何一个网络设备关闭,网络中的设备有可能把一段时间内没有数据的TCP连接直接关闭。这个问题,我用我本地的电脑连接SQL Azure的时候没出现过,但是在把程序移到Azure里面后就频频出现。在Azure里,如果一个TCP连接在差不多60秒的时间内没有数据,即会被关闭。解决这个问题的最好方法是让TCP连接定期发出心跳消息,保证连接不被中断(注意的是,这个解决方法不能避免SQL Azure关闭连接的问题,它们在不同的层面上)。SQL Server的.Net驱动实现已经包含了TCP心跳消息,但是Java的实现并没有,微软提供的解决方法是更改注册表,增加三个值:

注册表建

推荐值

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\KeepAliveTime

30000

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\KeepAliveInterval

1000

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpMaxDataRetransmission

10


实现的时候,在Role的definition文件里加上一个启动的task:

<Startup>    <Task commandLine="AddKeepAlive.cmd" executionContext="elevated" taskType="simple">    </Task></Startup>

AddKeepAlive.cmd的内容如下:

if exist D:\keepalive.txt goto donetime /t > D:\keepalive.txtREM Workaround for JDBC keep alive on SQL AzureREG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v KeepAliveTime /t REG_DWORD /d 30000 /f >> D:\keepalive.txtREG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v KeepAliveInterval /t REG_DWORD /d 1000 /f >> D:\keepalive.txtREG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v TcpMaxDataRetransmission /t REG_DWORD /d 10 /f >> D:\keepalive.txtshutdown /r /t 1:done

每个instance在第一次运行的时候,会重启一次系统,所以第一次初始化可能会比较慢。 更多请参考:http://msdn.microsoft.com/en-us/library/hh290696%28v=SQL.110%29.aspx


关键字:SQL Azure, Java, Grails, 连接中断


原创粉丝点击