精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品原创,禁止转载和任何形式的非法内容使用,违者必究。点名“简易百科”和“闲暇巴”盗用锐英源原创内容。
缓存能够提升程序性能,用Redis当缓存工具是经常用的方法,但是Redis是个第三方软件,怎样简单使用,用代码直接控制Redis,是个技术点,本文翻译自codeproject,提供技术方法,希望大家喜欢。
在本文中,我将展示如何将 Window 版本的 Redis Server 或其他可执行文件作为 Windows 服务运行。
在 CodeProject,我们使用 Redis 作为分布式缓存。我们存储大量信息,例如文章、论坛消息,并从缓存而不是数据库中检索这些项目。
Redis 允许我们存储和检索完整的文档,而不是查询各个部分的 SQL 并在每个请求上编写和格式化文档。这在我们的网站上是可能的,因为大多数信息的阅读量比写入量要多得多,并且某些信息(例如查看次数)可能有点陈旧。
在生产中,我们在 Linux 服务器上运行 Redis,在开发环境中,我们在 Window 7 桌面上运行 Redis 的 Microsoft 端口。问题是 Redis 并非设计为作为 Windows 服务运行。这意味着必须有人登录并运行 Redis 可执行文件。当 Chris 是唯一登录服务器的人时,这很好,但上周,我必须连接以安装我们的 Search Server 的副本以用于开发目的。不用说,这让 Chris 退出,并杀死了 Redis 服务器。我在我的会话下重新启动它。
回到我的机器上,我正在修复一个微妙的缓存错误,当我开始测试时,代码的行为就像是与 Redis 服务器的连接失败。由于我正在更改的代码与检测到 Redis 的连接问题有关,所以在我意识到 Chris 已经远程进入服务器之前,我转动了半个小时左右的时间,从而终止了我的会话和 Redis 服务器。
Chris 和我都尝试了许多推荐的方法来将 Redis 作为 Windows 服务运行,但都没有成功。在编写了几个 Windows 服务来支持各种 CodeProject 进程之后,我决定编写一个实用程序,它允许我们将 exe 作为 Windows 服务安装和运行。此实用程序称为Exe2Srvc.
Exe2Srv 是一个可以作为控制台应用程序运行或作为 Windows 服务安装的程序。此应用程序读取可执行文件的路径,以及来自它的 .config 文件的命令行参数,然后在新进程中启动可执行文件。
使用可执行文件的最简单方法是
对于我的测试, ,我从 Nuget 下载了 Redis,并将解决方案/packages/Redis-64.2.6.12.1/tools目录下的文件复制到 C:/Redis. 然后我将Exe2Srvc\bin\Release下文件复制到同一目录。
Exe2Srvc.exe.config 文件包含:
<?xml version="1.0" encoding="utf-8" />
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
</startup>
<appSettings>
<!-- set Cmd to the executable file name. -->
<!-- set CmdArg to any command arguments required. -->
<add key="Cmd" value="c:\Redis\redis-server.exe"/>
<add key="CmdArgs" value="c:\Redis\redis.conf --port 6379"/>
</appSettings>
</configuration>
如果可执行文件的路径包含空格,则路径需要用引号引起来。这可以通过将双引号字符串括在单引号中来完成,如下所示。
<?xml version="1.0" encoding="utf-8" />
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
</startup>
<appSettings>
<!-- set Cmd to the executable file name. -->
<!-- set CmdArg to any command arguments required. -->
<add key="Cmd" value='"c:Program Files\Redis\redis-server.exe"'/>
<add key="CmdArgs" value="c:\Redis\redis.conf --port 6379"/>
</appSettings>
</configuration>
该 Install.bat 文件必须以管理员身份运行,使用SC命令安装服务。
sc create Redis binpath="c:\Redis\Exe2Srvc.exe"
然后我使用服务管理器来配置服务并启动它。
双击 Redis 服务打开属性编辑器并选择恢复选项卡。设置选项以在出现错误时重新启动服务,如图所示。
选择常规选项卡。
Redis 现在已安装并作为 Windows 服务运行。使用redis-cli.exe 来测试连接。
创建一个可以作为 Windows 服务运行的控制台应用程序使用了 Steve Smith 向我展示的技术,并且基于Einar Egilsson的文章将Windows 服务作为控制台程序运行。
基本上,您创建一个控制台应用程序,并将Program 类更改为从ServiceBase继承. 在 Main中,该Environment.UserInteractive属性用于确定程序是从命令行运行,还是作为服务运行。
LoadConfiguration从方法中读取所需的命令和命令行参数。
/// <summary>
/// Loads the configuration parameters from the application config file
/// </summary>
private void LoadConfiguration
{
// Load the executable filename and command arguements from config file.
_cmd = ConfigurationManager.AppSettings["Cmd"];
_cmdArgs = ConfigurationManager.AppSettings["CmdArgs"];
if (string.IsNullOrWhiteSpace(_cmd))
throw new Exception("The appsetting 'Cmd' was not defined in the config file.");
}
这是从作为控制台应用程序启动时调用的OnStart方法调用的,或者在作为服务运行时由基础设施调用的方法调用。OnStart 在新文件中运行可执行文件,如下所示。MainServiceProcess
/// <summary>
/// When implemented in a derived class, executes when a Start command is sent to the
/// service by the Service Control Manager (SCM) or when the operating system starts
/// (for a service that starts automatically).
/// Specifies actions to take when the service starts.
/// </summary>
/// <param name="args";>
/// Data passed by the start command.
/// </param>
protected override void OnStart(string[] args)
{
if (Environment.UserInteractive)
{
string message = String.Format"Starting {0} at {1}.", _serviceName, DateTime.Now);
Console.WriteLine(message);
}
// loading the configuration file info here allows the service to be stopped,
// the configuration modified, and the service restarted.
LoadConfiguration();
// Start the executable.
ProcessStartInfo procInfo = new ProcessStartInfo(_cmd);
procInfo.UseShellExecute = false;
if (!string.IsNullOrWhiteSpace(_cmdArgs))
procInfo.Arguments = _cmdArgs;
_process = Process.Start(procInfo);
}
当服务停止时,该OnStop 方法被调用。这会杀死Process,等待它终止,然后处理Process. 确保您等待Process 终止,否则将导致无法正确停止的服务难以删除和修复。
/// <summary>
/// When implemented in a derived class, executes when a Stop command is sent to the service
/// by the Service Control Manager (SCM). Specifies actions to take when a service stops running.
/// </summary>
/// <remarks>Stops the background tasks.</remarks>
protected override void OnStop()
{
if (Environment.UserInteractive)
{
string message = String.Format("Stopping {0} at {1}.", _serviceName, DateTime.Now);
Console.WriteLine(message);
}
// Kill the process
if (_process != null)
{
_process.Kill();
_process.WaitForExit();
_process.Dispose();
_process = null;
}
}
我试图让它尽可能简单和灵活,但它只满足我最初的要求,即能够将 Windows 版本的 Redis 作为 Windows Server 运行。如果您有其他要求,请随时修改代码以满足您的需求。