简体   繁体   English

如何实施Exchange,例如内部SQL Server的可用性监视

[英]How to Implement Exchange like availability monitoring of internal SQL Server

We have an internal app( Thick Client ) that relies on our central SQL server. 我们有一个内部应用程序( 胖客户端 ),它依赖我们的中央SQL Server。 The app is a Desktop app that allows the users to work in "Offline" mode (eg Outlook). 该应用程序是一个桌面应用程序,允许用户在“脱机”模式下工作(例如Outlook)。 What I need to accomplish is a way to accurately tell if SQL is available or not. 我需要完成的是一种准确判断SQL是否可用的方法。

What I have so far: 到目前为止,我有:

I currently use the following method --> 我目前使用以下方法->

 internal static void CheckSQLAvailability()
    {
        using (TcpClient tcpc = new TcpClient())
        {
            try
            {
                tcpc.Connect(Settings.Default.LiveSQLServer, Settings.Default.LiveSQLServerPort);
                IsSQLAvailable = true;                    
            }
            catch
            {
                IsSQLAvailable = false;
            }
        }
    }

I am not crazy about this approach for the following reasons. 由于以下原因,我对这种方法并不感到疯狂。

  • Prone to false Negatives 容易产生假阴性
  • Needs to be " manually " called 需要被“ 手动 ”调用
  • Seems "smelly" ( the try/catch ) 看起来“很臭”( try / catch

I had thought to use a timer and just call this every X(3??) minutes and also, if a negative result, try a second time to reduce the false negatives. 我曾想过使用计时器,每隔X(3 ??)分钟才调用一次,如果结果为负,请尝试第二次以减少误报。

There is a similar question here --> Detecting if SQL server is running but it differs from mine in these ways: 这里有一个类似的问题-> 检测SQL Server是否正在运行,但在以下方面与我的不同:

  • I am only checking 1 server 我只检查一台服务器
  • I am looking for a reactive way versus proactive 我正在寻找一种被动的方式而不是主动的方式

So in the end, is there a more elegant way to do this? 最终,是否有更优雅的方法可以做到这一点? It would all be "in-network" detection. 都是“网络内”检测。

PS To offer some background as requested in an answer below: My app is a Basic CRUD app that can connect to our Central SQL Server or a local SQLExpress Server. PS为提供以下回答中所要求的背景知识:我的应用程序是基本的CRUD应用程序,可以连接到我们的Central SQL Server或本地SQLExpress Server。 I have a Merge Replication Module that keeps them in Sync and the DAL is bound to a User.Setting value. 我有一个合并复制模块,可以使它们保持同步,并且DAL绑定到User.Setting值。 I can, already, manually flip them from Central to Local and back. 我已经可以手动将它们从“中央”切换到“本地”,然后再返回。 I just want to implement a way to have it automatically do this. 我只想实现一种使其自动执行此操作的方法。 I have a NetworkChangeDetection class that works quite well but, obviously, does not detect the Remote SQL's. 我有一个NetworkChangeDetection类,可以很好地工作,但是显然不能检测到远程SQL。

Consider what the Windows Cluster monitor does for a SQL Server Cluster resource: it actually connects and runs a dummy query ( SELECT @@version ). 考虑Windows群集监视器对SQL Server群集资源的作用:它实际上连接并运行一个虚拟查询( SELECT @@version )。 This indicates that the SQL is running, is actively listening for requests, and is able to run a request and return a result. 这表明SQL正在运行,正在积极侦听请求,并且能够运行请求并返回结果。 For the clustering monitor the response to this query is the 'heartbeat' of the server and if it fails to get a response, for whatever reason, it may initiate a cluster failover. 对于群集监视器,对此查询的响应是服务器的“心跳”,并且如果由于任何原因而未能获得响应,它可能会启动群集故障转移。

Only connecting to TCP has several drawbaks in my opinion: 我认为仅连接到TCP会有一些麻烦:

  • it omits non-TCP protocols like local shared memory (LPC) or remote net pipes (SMB) 它省略了非TCP协议,例如本地共享内存(LPC)或远程网络管道(SMB)
  • it requires hard codded TCP port number as opposed to let the instance port listening auto-discovery do its work (SQL Browser and friends) 它需要硬编码的TCP端口号,而不是让实例端口侦听自动发现完成其工作(SQL Browser和朋友)
  • it only establishes that the OS level socket can be established, it does not validate that the SQL Server itself is in a runnable state (non-yielding scheduler might block network IO requests acceptance, scheduler overload and worker starvation may do the same, memory resource exhaustion etc etc). 它仅确定可以建立OS级别的套接字,而不验证SQL Server本身是否处于可运行状态(非收益调度程序可能会阻止网络IO请求接受,调度程序过载和工作人员饥饿可能会这样做,内存资源精疲力尽等)。

Unfortunately there is no way to get a notification from SQL Server itself of saying 'hey, I'm active, won't you send some requests?'. 不幸的是,无法从SQL Server本身获得通知,说“嘿,我很活跃,您不会发送一些请求吗?”。 I don't know all the details of your fat client ('thick app'), but perhaps you should investigate a different metaphor: clients do all work locally, on SQL Express instances, and these instances synchronize the data when the server is available. 我不知道胖客户端(“ thick app”)的所有详细信息,但也许您应该研究一个不同的隐喻:客户端在SQL Express实例上全部在本地工作,并且这些实例在服务器可用时同步数据。 Service Broker was designed specifically with this connection retry mode and it would hide the server availability due to its asynchronous loosely coupled programming API. Service Broker是专门为此连接重试模式设计的,由于其异步松耦合编程API,它将隐藏服务器的可用性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM