在 Linux / Mono 上运行 ServiceStack 的最佳方式是啥?

Posted

技术标签:

【中文标题】在 Linux / Mono 上运行 ServiceStack 的最佳方式是啥?【英文标题】:What is the best way to run ServiceStack on Linux / Mono?在 Linux / Mono 上运行 ServiceStack 的最佳方式是什么? 【发布时间】:2012-08-24 16:17:03 【问题描述】:

在ServiceStack website 上列出的它表明 ServiceStack 可以在 Mono 上运行:

XSP mod_mono FastCgi 控制台

这些不同的配置是什么?哪些配置更适合 Mono 上的 Web 服务?

【问题讨论】:

【参考方案1】:

Linux 更新

来自the v4.5.2 Release ServiceStack 现在支持 .NET Core,与 Mono 相比,它提供了显着的性能和稳定性改进,Mono 源自共享的跨平台代码库,并得到了微软资源充足、积极响应的团队的支持。如果您目前在 Mono 上运行 ServiceStack,我们强烈建议您升级到 .NET Core,以利用其卓越的性能、稳定性和自上而下支持的技术堆栈。

单声道更新

我们推荐的在 Linux 和 Mono 上托管 ASP .NET 站点的设置是使用 nginx/HyperFastCgi。我们已经在mono-server-config 发布了一个分步指南,从头开始创建一个 Ubuntu 虚拟机并完成部署/安装/配置/初始化脚本。

在注意到几个稳定性和性能问题后,我们不再推荐 MonoFastCGI。这篇博文对different ASP.NET Hosting options in Mono的性能、内存使用和稳定性进行了很好的分析。


发展

XSP 类似于 VS.NET WebDev 服务器——一个用 C# 编写的简单的独立 ASP.NET WebServer。这适用于开发或小工作量。您只需从 ServiceStack ASP.NET 主机的根目录运行它,即可在 http://localhost:8080 上使用它。

生产

对于外部 Internet 服务,您通常希望将 ServiceStack Web 服务托管为全功能 Web 服务器的一部分。适用于 Linux 的 2 个最受欢迎的全功能 Web 服务器是:

Nginx

使用Mono FastCGI 在Nginx 中托管ServiceStack ASP.NET 主机。

阿帕奇

使用mod_mono 在Apache HTTP Server 中托管ServiceStack ASP.NET 主机。

自托管

ServiceStack 还支持自托管,让您可以在独立的控制台应用程序(即没有 Web 服务器)中自行运行 ServiceStack Web 服务。当您不需要功能齐全的 Web 服务器的服务时,这是一个好主意(例如:您只需要在内部网络上托管 Web 服务)。

默认情况下,相同的 ServiceStack 控制台应用程序二进制文件按原样在 Windows/.NET 和 Mono/Linux 上运行。尽管如果您愿意,您可以轻松地将您的应用程序守护到run as a Linux daemon as outlined here。 wiki 页面还包含有关配置自托管 Web 服务以在 Nginx 或 Apache 反向代理之后运行的说明。

由于它非常适合 Heroku 的并发模型as detailed in their 12 factor app,因此自托管将是我们希望在不久的将来提供更多支持的领域。

ServiceStack.net Nginx / Mono FastCGI 配置

servicestack.net 网站本身(包括所有现场演示)使用 Nginx + Mono FastCGI 在Ubuntu hetzner vServer 上运行。

该命令用于启动FastCGI后台进程:

fastcgi-mono-server4 --appconfigdir /etc/rc.d/init.d/mono-fastcgi 
  /socket=tcp:127.0.0.1:9000 /logfile=/var/log/mono/fastcgi.log &

托管在使用XSP's WebApp File Format 指定的/etc/rc.d/init.d/mono-fastcgi 文件夹中的*.webapp 文件中定义的所有应用程序,例如:

ServiceStack.webapp:

<apps>
<web-application>
        <name>ServiceStack.Northwind</name>
        <vhost>*</vhost>
        <vport>80</vport>
        <vpath>/ServiceStack.Northwind</vpath>
        <path>/home/mythz/src/ServiceStack.Northwind</path>
</web-application>
</apps>

这会在后台运行 FastCGI Mono 进程,您可以通过将此规则添加到 nginx.conf 来让 Nginx 连接到该进程:

location ~ /(ServiceStack|RedisAdminUI|Redis***|RestFiles)\.*   
   root /usr/share/nginx/mono/servicestack.net/;  
   index index.html index.htm index.aspx default.htm Default.htm;  
   fastcgi_index /default.htm;
   fastcgi_pass 127.0.0.1:9000;  
   fastcgi_param SCRIPT_FILENAME /usr/share/servicestack.net$fastcgi_script_name;
   include /etc/nginx/fastcgi_params;  

它将任何以/ServiceStack/RedisAdminUI等开头的路由转发到FastCGI单声道服务器进程进行处理。以这种方式托管的一些示例应用:

http://www.servicestack.net/ServiceStack.Northwind/ http://www.servicestack.net/ServiceStack.Hello/ http://www.servicestack.net/RedisAdminUI/AjaxClient/ http://www.servicestack.net/Redis***/

对于那些对 servicestack.net 的完整 Nginx + FastCGI 配置文件感兴趣的人,available for download。

【讨论】:

【参考方案2】:

免责声明:我是 HyperFastCgi 服务器的作者,ceco 的回答中提到了博客文章的作者

带有HyperFastCgi 的nginx 做这个工作。 HyperFastCgi 不会像单声道 fastcgi 服务器那样泄漏内存并且执行速度更快,因为它使用低级单声道 API 在应用程序域之间传递数据,而不是跨域调用的慢单声道 JIT 实现。它还可以选择使用原生 libevent 库进行套接字通信,这比当前的单声道 System.Net.Sockets 实现快大约 1.5-2。

HyperFastCgi 的主要特点:

允许使用 3 种不同的方式来处理套接字和跨域通信: Managed Listener with Managed Transport(仅使用托管代码,异步 System.Net.Sockets。由于 JIT 跨域调用缓慢,单声道速度较慢) Managed Listener with Combined Transport(使用异步 System.Net.Sockets 作为侦听器,使用低级单声道 API 进行跨域调用。快得多) Native Listener(使用原生libevent作为socket库和低级mono API进行跨域调用,性能最佳) 允许以多种方式并行 Web 请求:使用 ThreadPool、.NET 4.5 任务或单线程。最后一个选项与@​​987654325@ 结合使用使网络服务器像NodeJS 一样工作:所有请求都以异步方式在单线程中处理。 允许在完全不使用 System.Web 的情况下编写简单的请求处理程序。这将请求的处理性能提高了 2-2.5 倍。

【讨论】:

【参考方案3】:

evhttp-sharp - 带有 NancyFx 主机的 http 服务器

https://github.com/kekekeks/evhttp-sharp

非常快,几乎比 nancy-libevent2 快 4 倍。

http://www.techempower.com/benchmarks/#section=data-r8&hw=i7&test=json&s=2&l=2

有不同配置的测试结果:

每秒 JSON 响应:

evhttp-sharp 91,557 nancy-libevent2 17,338 servicestack-nginx-d 953 南希 896 aspnet-jsonnet-mono 863

【讨论】:

【参考方案4】:

有一篇关于使用 ServiceStack 的 Mono 性能的有用且相对较新的博客文章。我认为它可能对一些即将决定如何托管服务的人有用:Servicestack performance in Mono

正如它所说 - FastCGI Mono 服务器有 的内存泄漏,我可以确认。我使用 Mono 3.2.8 和 Nginx 1.4.6 以及 FastCGI Mono Server 3.0.11 和使用 ServiceStack 3.9.71 编写的服务在 Ubuntu Desktop 14.04 上运行 ab -n 100000 -c 10 http://myurl。我认为我使用哪个版本的 ServiceStack 并不重要,因为 FastCGI Mono Server 是一个漏洞。它吃掉了所有可用的内存 - 总共 2GB 中的大约 1Gb。

此外,Nginx + FastCGI Mono Server 的性能,至少与其他解决方案相比是这样。我的示例 REST 服务每秒大约有 275 个请求。博客作者查看了 FastCGI Mono Server 的代码并决定编写自己的实现。出于某种原因,它无法正常工作,至少在我的机器上是这样。

所以我想,关键是您不应该使用 FastCGI Mono 服务器。除非你想经常重启你的盒子。

由于这篇文章大多是负面的,我应该说一下我对托管服务的意图是什么。我可能会使用继承 Nginx 后面的AppHostHttpListenerLongRunningBase 的 AppHost 进行自托管。使用上面相同的示例 REST 服务,我每秒收到大约 1100 个请求。更好的消息是该进程没有明显的泄漏,我用大约 1 000 000 个请求对其进行了测试,并且该进程消耗了

附:我不是这篇博文的作者 :)

【讨论】:

【参考方案5】:

在生产中我们使用带有 unix 文件套接字的 nginx

在使用 nginx、服务堆栈和单声道进行套接字通信时,我们发现了一个错误/内存泄漏。这是有 500 个并发请求,而您预计 CPU 和内存会出现峰值,但它再也不会下降。我们没有做任何进一步的测试来发现问题出在哪里,但是有一个用xamarin bugzilla 记录的错误似乎与我们遇到的问题相似。基本上我们尝试了以下方法,这对我们来说已经足够了。

我们切换到使用带有以下命令参数的 unix 套接字

fastcgi-mono-server4 /filename=/tmp/something.socket /socket=unix /applications=/var/www/

我们使用这种方法遇到的问题是,每次运行 fastcgi-mono-server4 时,socket 文件的权限都会改变,所以在启动 fastcgi-mono-server4 后必须更正它们!另一个缺点是在我们的机器上它只能处理大约 120 个并发请求。然而,目前这对我们来说并不是一个真正的问题,你总是可以产生更多的进程。

希望对你有帮助

【讨论】:

感谢分享!你可以在运行 fastcgi-mono-server4 后直接修复权限吗?如果是这样,您可以将其包含在您的答案中吗? 是的,您可以在运行 fastcgi-mono-server4 后直接修复权限。首先,您可以在 /tmp/something.socket 上执行 chmod 777,显然不要在生产中执行此操作!基本上 nginx 和 fastcgi-mono-server4 都需要写入 /tmp/something.socket 的权限 很好的答案,看了这个之后,我尝试在我的生产服务器中实现并通过为 nginx 和 fastcgi-mono-server4 运行相同的用户(例如:wwwdata)成功处理权限问题。谢谢。但并不真正了解如何通过生成更多进程来处理更多并发(您的意思是在其他机器上运行并将 nginx 作为负载均衡器放在前面?) @AntonHasan 当您将 fastcgi 与 nginx 一起使用时,您实际上是将所有请求代理到 fastcgi 进程中。 Nginx 不会自动为您生成新进程。这就是为什么你需要运行 fastcgi-mono-server4。但是是的,基本上你需要将 nginx 作为负载均衡器运行。你可以在一个盒子上实现这一点,但你是对的,你最好在前面使用 ha proxy/nginx,然后在后面使用多个服务器。希望这会有所帮助。 Unix 域套接字的性能通常优于 TCP 套接字,但会限制您从本地计算机扩展的能力:***.com/questions/257433/…

以上是关于在 Linux / Mono 上运行 ServiceStack 的最佳方式是啥?的主要内容,如果未能解决你的问题,请参考以下文章

确定 Linux 上运行的是哪个版本的 Mono?

使用 MPI.NET 和 Mono 框架在超级计算机的 linux 节点上执行分布式计算

在Amazon Linux上安装mono时出错

是否可以在Linux或Mac上的Mono上安装Sitecore CMS?

HttpListener 在 Mono 上运行良好吗?

从 Mono 上运行的 C# 进程运行 C++ 应用程序。运行检测器错误