使用 Windows 95 和 Linux 创建客户端-服务器数据库系统

作者:Liu Kwong Ip

大约半年前,我们开始了一个名为 NORA 的项目,旨在为香港一家私人牙科诊所开发信息系统。基本要求是诊所内的任何客户端 PC 都可以检索和编辑临床信息,包括患者文件夹、预约簿、实验室工作等。此外,用户希望他们可以使用同一系统从另一家诊所访问数据。该系统目前正在进行 Beta 测试。我们在这个项目中获得了一些宝贵的经验,对于希望开发类似系统的人,特别是对于中小型企业来说,这些经验可能很有用。

我们确定了以下要求

  • 客户端-服务器数据库系统

  • 多站点(分散式)

  • 按需连接局域网

  • 拨号服务

  • Windows 95 客户端

  • Big5 字符集支持

  • 低事务率

  • 可移植性

由于该系统将同时被多个用户(牙医和护士)使用,因此需要客户端-服务器系统。用户对计算机了解不多,但他们了解微软。他们坚持使用 Windows 95 作为客户端 PC 的操作系统,以便他们可以在同一台机器上使用他们最喜欢的办公套件。对于服务器部分,他们没有偏好,所以我们可以决定。我们考虑了 Windows NT 和 Linux。在考虑了稳定性、易于安装、成本、灵活性以及上面列出的要求后,我们选择了 Linux。我们认为我们做出了正确的选择;否则,其他系统要求可能无法轻松实现。

该系统被一组诊所使用。用户希望可以从任何诊所轻松检索和更新所有数据。我们考虑在单个大型服务器上实施该系统,所有诊所都通过电话线或 ISDN 连接到该服务器。但是,我们发现,不仅通信成本和效率比分散式系统(即每个诊所都有自己的服务器)更差,而且如果另一个诊所加入集中式系统,还需要做很多工作,因为两个数据库中的数据都需要合并。

由于我们选择在每个诊所都设置一台服务器,因此诊所之间的连接应按需建立,即仅在需要时才建立连接。我们可以为每个客户端安装一个调制解调器,以便可以拨打另一个诊所的服务器以独立访问数据。然而,这不是一种有效的方法,因为每台客户端机器都需要一个调制解调器和电话线,并且大部分时间它们都处于空闲状态。我们建议连接由服务器建立,客户端通过服务器按需访问另一个诊所的数据。

我们尝试在 Linux 上使用 diald(拨号守护进程)来提供此功能。然而,大多数关于 diald 的文档都假设用户在独立工作站上使用它,或者拨号连接 ISP 以访问互联网。结果是连接不是双向的,即互联网上的机器无法访问本地工作站。此外,文档中的配置没有考虑在同一台机器上具有拨入服务,并且这两种服务可能兼容也可能不兼容。

我们找到了一种方法,可以在 Linux 上和谐地配置 diald 和拨入服务。因此,一个诊所中的所有机器都可以基于按需拨号访问另一个诊所中的数据库服务器,而另一个诊所中的机器可以同时访问第一个诊所中的数据库。

需要拨入服务来处理来自另一个诊所的服务器的拨入请求,以连接两个局域网。此外,用户希望即使在家中,也可以通过带有调制解调器的独立 Windows 95 工作站访问数据。

如上所述,用户坚持使用 Windows 95 作为前端。找到在 Windows 95 中连接客户端软件以显示 Linux 服务器中数据的方法是一个问题。这是因为某些 Linux 数据库服务器不提供此功能。

服务器的另一个限制是它必须支持 Big5 字符,因为大多数患者在注册时都使用他们的中文姓名和地址。这几乎迫使我们最终选择了数据库服务器 MySQL 服务器。

我们估计了系统服务器的事务率,发现它应该相对较低,在高峰期大约每分钟执行十次 SQL。我们认为这种特性对于中小型企业应用程序来说很常见,因此数据库服务器的加载性能并不重要。

最后,我们始终牢记可移植性。即使客户端软件是在 Windows 95 上实现的,我们也希望将来将其移植到另一个平台。

数据库服务器考虑因素

在撰写本文时,用于 Linux 的 Informix-SE 才刚刚可用,Oracle 也开始将其数据库服务器移植到 Linux。我们没有考虑这两个流行的数据库。我们只考虑具有以下基本属性的数据库服务器

  • 它遵循关系模型并支持 SQL(或 SQL 的子集)。关系模型已成为现代数据库服务器的标准。我们的客户端软件可以使用 SQL 以标准方式与数据库通信。因此,即使我们在将来更改数据库服务器软件,我们的大部分客户端代码也无需更改。

  • 它是免费的或低成本的。我们相信可以在 Linux 世界中找到免费或低成本的优秀软件,因此我们首先考虑了免费的数据库服务器。如果没有满足我们的要求,我们可能会考虑商业数据库服务器。

  • 如果可能,它是开源的。我们想要整个系统的源代码,包括操作系统、客户端-服务器软件和数据库服务器,以便我们的系统不会受到第三方任何标准或格式更改的影响。当然,我们无法获得 Windows 95 的代码,这就是我们想要将客户端软件移植到另一个平台的原因。

从四个方面比较了数据库服务器:可用的 C API、可用的 ODBC 驱动程序、Big5 代码支持和并发控制方法。C API 对于在 Linux 上运行的客户端软件非常重要。ODBC 驱动程序适用于在 Windows 95 上运行的客户端软件。如上所述,Big5 代码支持是我们系统的基本要求之一。由于它是多客户端系统,因此防止并发客户端数据访问相互干扰的方法也很重要。我们对四个流行的数据库系统进行了调查:PostgreSQL、Beagle SQL、mSQL 和 MySQL。所有这些系统的源代码都是可用的。PostgreSQL 和 Beagle SQL 都是免费的。mSQL 如果您在学术和注册慈善组织中使用它是免费的,否则单许可证的价格为 250 美元。MySQL 如果您不出售它是免费的;否则,每份副本的价格为 200 美元。结果如表 1 所示。

表 1。

MySQL 被选为我们的数据库服务器。最重要的原因是它具有适用于 Windows 95 的 ODBC 驱动程序,并且它支持 Big5 字符。MySQL 是一个多线程进程,每个连接都有一个线程。此外,还提供了许多支持实用程序,例如表修复工具。我们为 Big5 支持重新编译了它。在 Beta 测试期间,我们发现该系统在 Red Hat 4.2 上稳定、高效且可靠。但是,我们发现即使我们严格按照手册操作,它也无法在 Red Hat 5.0 上成功编译和运行。我们认为主要原因是库不兼容。

客户端考虑因素

我们考虑了适用于 Windows 95 的不同 C++(或 C)编译器,最终选择了 Borland (Inprise) C++Builder 作为我们的客户端软件开发环境。C++Builder 中有一些可视化对象(类似于 Delphi 和 Visual Basic),可以直接访问数据库中表的内容。它们应该简单易用。但是,当程序变得很大时,维护具有这些类型对象的代码并不容易,因为每个数据库小部件的行为几乎是独立的。我们决定开发一个数据库对象层,作为可视化对象和数据库内容之间的桥梁。SQL 语句嵌入在数据库对象中。这样,临床对象可以自然而一致地定义为数据库对象。此外,可以在此对象层中实施安全检查,以保护显示在可视化对象上的数据。我们希望软件的可移植性也将得到提高。

系统架构

图 1。

NORA 的拟议系统架构如图 1 所示。为了简化讨论,我们假设连接发生在两个服务器之间。配置可以推广到多个服务器之间的连接。对于每个诊所,都有一台用于数据库和 diald 的 Linux 服务器。Windows 95 客户端通过 ODBC 驱动程序连接到本地或远程数据库服务器。diald 在需要时启动与另一台服务器的连接。

配置拨号服务器

现在我们来讨论连接和配置。基本上,我们将遵循关于这些主题的常见问题解答和手册页。由于需要一个代理来接收来自另一台计算机的拨号呼叫,我们安装了 mgetty 来应答来自调制解调器的呼叫。如果呼叫是正常的数据通信,将执行 login 以提示另一侧的用户。mgetty 的一个优点是,如果呼叫是传真,它也可以充当传真接收器,将其转发到电子邮件或打印出来。mgetty 应该由 init 启动,并在 inittab 中指定。

另一侧的用户可以在登录到 Linux 服务器后启动 pppd。pppd 的选项文件应保持最简单的形式,即不应指定 IP 地址、子网掩码等。这是必要的,因为此配置由 pppd 的任何执行实例使用,甚至是由 diald 启动的实例使用。例如,如果在选项文件中指定了 IP 地址,则拨出连接(通过 diald)IP 地址将固定为相同的地址。这是不正确的,因为此地址应在服务器拨出时由目标服务器分配。此处显示了一个建议的 PPP 选项文件,名为 options

proxyarp
lock
crtscts
modem

列表 1。

我们将其他配置选项留给连接脚本。列表 1 中显示了一个用于拨入 PPP 启动的脚本示例,名为 startppp。应该注意的是,defaultroute 对于来自独立 PC 的拨号连接可能不是必需的,但对于 LAN 连接是必需的。否则,拨号连接无法路由到 LAN 中的所有机器。此外,我们跳过了 pppd 的连接脚本,因为它可以在常见问题解答和手册页中找到。

您可以使用 Windows 95 或另一台使用 PPP 的 Linux PC 拨入服务器来检查此阶段的完成情况。登录后通过执行 startppp 启动 PPP。外观应类似于拨号连接到 ISP。

配置按需拨号服务器

如上所述,我们应该以对称的方式配置按需拨号服务器,即连接可以由任何服务器启动,并且一旦建立连接,任何一方的任何机器都可以访问另一方的服务器,无论连接从哪里启动。在这种情况下,diald 文档中总是提到的用于连接到互联网的 IPtranslation 是不需要的。这将简化 diald 的配置。

我们在服务器上安装 diald,并使其在系统启动后自动启动。diald.conf 配置文件的示例如列表 2 所示。

列表 2。

当 diald 启动时,将执行 addroute 脚本。对远程站点的所有访问都路由到激活 diald 的 IP 地址(diald.conf 中的 aaa.bbb.fff.eee)。例如

#!/bin/sh
/sbin/route add -net aaa.bbb.fff.0 \ # remote LAN
                                              # IP address
netmask 255.255.255.0 gw $4 \
window 2048 metric $5 dev $1

我们跳过了 diald 的连接脚本,因为它应该类似于 pppd 的连接脚本。应该注意的是,本地 LAN 中所有客户端的默认网关应更改为本地服务器的 IP 地址。您可以通过从本地 LAN 中的任何 PC 访问(例如,使用 ping、FTP 或 TELNET)远程服务器来检查此阶段的完成情况。调制解调器将拨出,服务器将成功登录到远程服务器。但是,如果远程服务器已经以相同的方式配置了 diald,您将不会收到来自远程服务器的任何响应。

系统集成

两个服务器之间使用 diald 的连接被阻止的原因可以解释如下。由于两个服务器都准备好连接到另一侧,因此如果任何数据包的目标是另一侧,则两个服务器的路由表都具有到达激活 diald 的 IP 地址的路由。因此,例如,serverA 启动与 serverB 的连接,并在连接建立后将数据包发送到 serverB。但是,返回的数据包无法返回到 serverA,因为 serverB 中到 serverA 的默认路由是在 serverB 中启动 diald。ServerA 无法通过已建立的连接接收来自 serverB 的返回数据包。

我们通过使用 pppd 的 ip-up.localip-down 脚本来解决此问题。ip-up.local 在 pppd 成功建立连接时执行。因此,当 pppd 启动连接时,我们删除 serverB 中到 serverA 的路由表条目。以下是 ip-up.local 的示例。

/sbin/route del aaa.bbb.fff.0 # remove remote IP
                                  # route

应该注意的是,该脚本对来自独立 PC 的拨号服务没有负面影响。当连接完成时,应恢复路由表。因此,ip-down 脚本文件(在 pppd 停止连接时执行)像这样使用

#!/bin/bash
/usr/lib/diald/addroute sl0 \
255.255.255.0 \
aaa.bbb.ccc.ddd \       # server IP address
aaa.bbb.fff.eee \       # IP address will be activated
                        # by diald
1
基本上,它与 addroute 脚本相同,参数与 diald 启动时相同。在此阶段之后,您应该能够从本地 LAN 中的任何机器访问远程服务器。远程服务器可以同时访问本地服务器。此外,独立 PC 可以从任何地方拨号并访问服务器。
结论和未来计划

NORA 已在多个站点安装和测试了三个月。服务器机器上没有发生过一次崩溃或故障。我们还设置了其他服务,例如文件和打印服务器 (Samba)、Web 服务器 (Apache) 等。Linux 确实是一个稳定、灵活且可扩展的操作系统。

我们计划使用 ISDN 替换传统的电话线,以缩短 X 射线照片等大型对象的传输时间。我们还在将客户端软件移植到 Linux,以便可以提高整个系统的稳定性。

本文中引用的所有列表都可以通过匿名下载文件 ftp.linuxjournal.com/pub/lj/listings/issue67/3191.tgz 获取。

Creating a Client-Server Database System with Windows 95 and Linux
Liu Kwong Ip (kiliu@netvigator.com) 获得了香港城市理工学院信息技术理学学士学位。他目前在北方口腔科学研究所担任系统顾问。
加载 Disqus 评论