随笔-27  评论-184  文章-11  trackbacks-16

Mono on Linux 开发与实践札记(1)

最近有个政府项目,客户指定服务器程序必须跑在Linux上面,于是乎我们这帮Linux菜鸟立马开装Linux系统并部署Mono环境。因为对Linux实在不熟的缘故,故在RedHat Enterprise Linux 6中始终没有将MonoDevelop跑起来,于是团队中有同事提议“干脆转Java平台算哒”,哎呦,这么“反动”的想法必须得镇压在萌芽状态。好吧,我承认有些许的个人主观因素作祟,但终究还是需要些冠冕堂皇理由的:

  1. 因为公司现有所有产品都是基于.NET平台,绝大数开发人员也只有.NET开发经验,这样的平台迁移是个非常大成本的事件,而且涉及公司的整个软件开发的方向性转移,绝不可贸然行事。
  2. 我一直主张将所有产品统一开发平台,最终将各条产品线全部基于自己研发的插件框架,如果并行Java和.NET两个开发平台,其中涉及的开发量和代码移植、版本同步、双向兼容……想想就是一个浩大而繁琐的工程,这样的焦油坑一定要避免陷入进去。
  3. 目前的问题其实只是团队对Mono on Linux的经验匮乏,这个问题还不至于严重到需要迁移开发平台,起码我们还有Mono这样一根救命稻草。所以,我们要做的只是尽快熟悉Linux和积累Mono on Linux上面的一些移植经验,当然,我知道把C#代码移植过去通过Mono的编译并不难,问题在于有些API的细节差异和某些代码契约需要通过一定时间的经验来规避某些小陷阱,但是,这些都是可以解决的。
  4. Mono现在最新稳定版本是2.10.2,对C# 4.0已经支持的很完整了。而且后面很快会有ASP.NET MVC3的完整实现,虽然没有看到对ADO.NET EntityFramework的支持计划,但是,我们曾经实现过以DataSet为数据载体的数据访问框架,所以完全可以借鉴ADO.NET EF的设计思想去实现一个适度ORM数据引擎,当然这个事情得推后一点才有精力去做,但是想想就是一件多么有趣的事情啊。

上面晓之以理,下面就该动之以情了,你看这次的Android版的警务通就是用Java来搞的,没有使用那个MonoDroid吧,为啥?因为Mono for Android实在太不成熟了,用它写的程序的无论是体积还是运行效率都没法跟人家比,确实不在一个等级。总而言之,量体裁衣、具体对待。

部门会餐后,俺决定从这个项目组开始逐步进行双机开发,每人配两台电脑,一台装Windows、一台装Linux,在Windows中用VS开发,调试通过后签入SVN中,再在Linux中签出使用MonoDevelop进行一遍单元测试,不用虚拟机,一切原生态同步开发,提升每个开发人员对Linux的熟悉和积累对Mono on Linux的开发经验,于公于私都是非常给力的!


RHEL6中MonoDevelop装不上,咱没功夫跟它耗,赶紧上OpenSUSE和CentOS,这两个都是MonoDevelop官网的主荐平台,果然很给力相当的顺。下面是今天(2011-7-5)将一些后台代码移植到Mono on Linux中的实践札记:

  1. 众所周知Linux的文件系统路径是区分大小写的,所以在代码中千万不能简单拼接文件路径,推荐使用 System.IO.Path 类中的相关方法进行路径操作,另外,对于文本中的分行要使用 Environment.NewLine属性,或者 AppendLine 之类的方法来处理以规避操作系统的差异。
  2. 避免使用Win32 API的P/Invoke操作,这点好在Linux上只是跑服务器端代码,所以基本不会涉及。

今天移植的两个类库时,只碰到下面两个问题花了一点时间,就运行测试通过了,好爽。

一、在.NET 4.0的System.Type中新增了这个GetType(…)方法重载:

public static Type GetType(string typeName, Func<AssemblyName, Assembly> assemblyResolver, Func<Assembly, string, bool, Type> typeResolver, bool throwOnError)

  我的代码是这样使用的:

public static Type GetType(string typeFullName)
{
     if(string.IsNullOrWhiteSpace(typeFullName))
         return null;

     return Type.GetType(typeFullName, assemblyName =>
     {
         Assembly assembly = ResolveAssembly(assemblyName);

         if(assembly == null)
             assembly = LoadAssembly(assemblyName);

         return assembly;
     }, null, false);
}

在.NET中一切正常,但是在Mono on Linux中无法正常解析,经查看微软的源码和Mono源码后,发现他们的对于第三个typeResolver参数的处理策略不同,故而将上述代码改成:

public static Type GetType(string typeFullName)
{
    if(string.IsNullOrWhiteSpace(typeFullName))
        return null;

    return Type.GetType(typeFullName, assemblyName =>
    {
        Assembly assembly = ResolveAssembly(assemblyName);

        if(assembly == null)
            assembly = LoadAssembly(assemblyName);

        return assembly;
    }, (assembly, typeName, ignoreCase) =>
    {
        if(assembly == null)
            return null;
        else
            return assembly.GetType(typeName, false, ignoreCase);
    }, false);
}

后来发现对解析像 System.Int32 这样的简写类型名失败,原因就在于typeResolver参数对应的委托回调中传入的assembly参数为空(null),故而将其后的代码(黄色高亮)行改为:return Type.GetType(typeName, false, ignoreCase);即可!

二、在.NET中使用System.Net.HttpListener进行侦听后,如果进程被强制关闭Windows操作系统会回收它所占用的地址和端口(注意:该点未经证实,纯属个人瞎猜),故重新运行该程序后顺利重启HttpListener。但是在Mono on Linux中却行不通,当强制关闭进程后,再次运行会抛出 System.Net.Sockets.SocketException,提示“Address already in use.”这表示Socket已经被占用,需要手动将占用的Socket关闭,那该怎么做呢?首先查出机器中的网络状态,然后找到占用的该Socket的进程,再将该进程Kill掉即可。找到如下操作步骤可解决之:

在Linux终端中,键入这个命令:lsof –i

如果当前用户不是root可能什么也看不到,那么请切换到root用户权限,如:sudo lsof -i

上面命令会提示你输入root根用户的密码,然后即可看到当前机器中的网络占用列表了,这时如果人品没问题的话,应该可以看到cammand为mono的占用记录,如果你清楚自己占用的端口号的话,请这么查看(以88端口为例):lsof –i:88 或者 sudo lsof –i:88

你找到占用程序的进程Id(PID),然后使用kill命令干掉它即可,假设PID为1234:kill 1234 或者 sudo kill 1234


好了,再次运行程序,又跑起来了!Good,先到这,还会有很多问题等着我们的,到时再写吧!


作者:钟峰(Popeye Zhong)目前是 武汉中科通达高新技术有限公司 的软件产品开发负责人,主要负责公司软件产品的技术架构和公共框架开发。他曾经使用 C 语言做过图形程序设计,在相当长的一段时期内从事 COM/COM+ 组件的开发和设计工作,并且短暂的做过 Lotus/Notes 和 Dialogic 语音卡程序的开发,从2003年初开始使用.NET这个充满趣味和挑战的开发平台,还领导过.NET平台下的 Windows Mobile 几个项目的开发,对WinForm和WebForm均比较熟悉。感兴趣的除了企业应用架构设计、组件开发、安全、图像处理外还对汽车和枪械模型、边境牧羊犬有浓厚的兴趣。如果希望与他联系,可访问 http://www.cnblogs.com/sw515 或者Email Zongsoft # gmail.com (将#换成@)
posted on 2011-07-06 19:43 钟少 阅读(2545) 评论(26) 编辑 收藏

评论:
#1楼 2011-07-06 19:52 | Jeffrey Zhao      
引用而且后面很快会有ASP.NET MVC3的完整实现

哥,开源的,自己编译一下应该就好了吧……MVC 2的时候我就这么做的。

 回复 引用 查看   
#2楼 2011-07-06 20:09 | 路过秋天      
数据框架可以考虑: CYQ.Data 数据框架,在mono上跑过测试过的,而且开源版本是免费的。
 回复 引用 查看   
#3楼 2011-07-06 20:41 | shanyou      
钟Sir顺利进入Mono/Linux,祝贺
 回复 引用 查看   
#4楼 2011-07-06 20:50 | 阿不      

引用Jeffrey Zhao:
引用而且后面很快会有ASP.NET MVC3的完整实现

哥,开源的,自己编译一下应该就好了吧……MVC 2的时候我就这么做的。

MVC3比较麻烦,因为那个Microsoft开头的dll不兼容。不过,2.10.2已经兼容了MVC3了,这个我已经尝试过了,可以正常跑起来

 回复 引用 查看   
#5楼[楼主] 2011-07-06 20:52 | 钟少      
@shanyou
哈哈,善友你个Mono/Linux资深人士就不要笑话俺了。

悲催,这两天Linux都重装了好几遍,还有啊,我用MonoDevelop 2.4 在调试过程中感觉不太给力、速度慢、功能不稳定,有时进行单步调试都要小等一会,而且多次中断调试后,很容易导致MonoDevelop直接崩溃,无语滴说~ 看来实际开发还得用VS,这个MonoDevelop只能用来做移植性调试用。

 回复 引用 查看   
#6楼 2011-07-06 23:07 | Nick.Lee      
企业主流Linux还是RedHat,高效而稳定,对其他兼容性好
OpenSUSE这个在中国企业的应用度不高,性能能不能经得起考验,难说.
这个焦油坑也很大,后面未知问题会随着应用深入而显露。

 回复 引用 查看   
#7楼 2011-07-06 23:13 | 天行健 自强不息      
以上回复的都是牛人啊,我来参观一下
 回复 引用 查看   
#8楼 2011-07-07 00:35 | Ariel Lu      
好文,希望像楼主这样把mono用于生产环境的先驱者能够多分享经验
 回复 引用 查看   
#9楼 2011-07-07 00:58 | 小赖同学      
会火
 回复 引用 查看   
#10楼[楼主] 2011-07-07 01:18 | 钟少      
引用Nick.Lee:
企业主流Linux还是RedHat,高效而稳定,对其他兼容性好
OpenSUSE这个在中国企业的应用度不高,性能能不能经得起考验,难说.
这个焦油坑也很大,后面未知问题会随着应用深入而显露。


  呵呵,很高兴看到这么多热心网友的回帖。非常感谢Nick.Lee的提醒!这次也是因为项目周期仓促而项目组成员又都对Linux不熟悉,没办法只能先这么用OpenSUSE顶着做移植开发吧,初步打算先在MonoDevelop on OpenSUSE上将项目全部运行测试通过后再转移到RHEL6上去,因为在RHEL6上面的Mono运行时环境是搭好没问题的,关键是MonoDevelop暂时还跑不起来。

  另外,经过这两天的鼓捣,我们感觉CentOS对Mono的友善度非常不错,不像RHEL6那么绕弯子,CentOS这个由社区主导的基于RHEL代码的免费版无论稳定性还是用户口碑都相当不错,有先部署它试试的冲动……

 回复 引用 查看   
#11楼 2011-07-07 01:53 | Jeffrey Zhao      
引用钟少:
@shanyou
哈哈,善友你个Mono/Linux资深人士就不要笑话俺了。

悲催,这两天Linux都重装了好几遍,还有啊,我用MonoDevelop 2.4 在调试过程中感觉不太给力、速度慢、功能不稳定,有时进行单步调试都要小等一会,而且多次中断调试后,很容易导致MonoDevelop直接崩溃,无语滴说~ 看来实际开发还得用VS,这个MonoDevelop只能用来做移植性调试用。

MonoDevelop还十分不好用,我也是VS里编辑和编译,Mono里跑。

 回复 引用 查看   
#12楼 2011-07-07 08:12 | 瑞雪年      
趁着还在前排,我也推荐一个mono linux下可用的开源数据访问组件:
http://dac.codeplex.com

 回复 引用 查看   
#13楼 2011-07-07 08:47 | yunpeng      

 回复 引用 查看   
#14楼 2011-07-07 09:10 | 银河      
引用Jeffrey Zhao:
引用钟少:
@shanyou
哈哈,善友你个Mono/Linux资深人士就不要笑话俺了。

悲催,这两天Linux都重装了好几遍,还有啊,我用MonoDevelop 2.4 在调试过程中感觉不太给力、速度慢、功能不稳定,有时进行单步调试都要小等一会,而且多次中断调试后,很容易导致MonoDevelop直接崩溃,无语滴说~ 看来实际开发还得用VS,这个MonoDevelop只能用来做移植性调试用。

MonoDevelop还十分不好用,我也是VS里编辑和编译,Mono里跑。

很赞同老赵的观点。
还有,开发机中可能需要 MonoDevelop,生产机中就不需要 MonoDevelop 了。

支持楼主的决定,不迁移到 Java 平台 。

 回复 引用 查看   
#15楼 2011-07-07 09:24 | 长春_庞家琛      
楼主 加下QQ 387934897
 回复 引用 查看   
#16楼 2011-07-07 09:41 | RubyPDF      
引用钟少:
@shanyou
哈哈,善友你个Mono/Linux资深人士就不要笑话俺了。

悲催,这两天Linux都重装了好几遍,还有啊,我用MonoDevelop 2.4 在调试过程中感觉不太给力、速度慢、功能不稳定,有时进行单步调试都要小等一会,而且多次中断调试后,很容易导致MonoDevelop直接崩溃,无语滴说~ 看来实际开发还得用VS,这个MonoDevelop只能用来做移植性调试用。

在SharpDevelop下也碰到过同样的问题,后来忘记怎么解决的了

 回复 引用 查看   
#17楼 2011-07-07 10:12 | 刘江北      
跟各位大哥学习~~~
 回复 引用 查看   
#18楼 2011-07-07 11:05 | Jeffrey Zhao      
引用银河:
很赞同老赵的观点。
还有,开发机中可能需要 MonoDevelop,生产机中就不需要 MonoDevelop 了。

很显然这个Linux是用来做Server的吧,这样连GUI都不需要也可以……

 回复 引用 查看   
#19楼 2011-07-07 11:10 | Jeff Wong      
学习
 回复 引用 查看   
#20楼 2011-07-07 11:13 | 小城故事      
支持LZ,Java虽还有生命力,但从.Net转Java就是倒退了
 回复 引用 查看   
#21楼 2011-07-07 11:26 | iTech      
加油干linux
 回复 引用 查看   
#22楼 2011-07-07 11:53 | henry      
其实直接在win下装个MonoDevelop编译后,copy到linux下就行了。我一般都是用vs编写,如果要在linux下跑就用MonoDevelop编译。还有linux下装mono最好是编译安装。
 回复 引用 查看   
#23楼 2011-07-07 19:10 | Simon.Wong      
Mark一下,一直想玩,但一直工作太忙,这个星期六天试一下!
 回复 引用 查看   
#24楼 2011-07-08 15:20 | Snag      
-.- monodevelop 我也用过,那时候 我是直接抄代码 从VS里抄进去,别的都还好 就是控件的 浪费了很多时间。 也有Windows版的monodevelop 不知道是不是差不多 那时候也没试, 这个跑起来 感觉就是很不稳定 会突然出什么错, 而且 发布我不知道咋发布,弄来弄去 好像都是他直接把debug里的文件复制到发布去的.... good luck啊。
 回复 引用 查看   
#25楼 2011-07-08 15:22 | Snag      
引用钟少:
@shanyou
哈哈,善友你个Mono/Linux资深人士就不要笑话俺了。

悲催,这两天Linux都重装了好几遍,还有啊,我用MonoDevelop 2.4 在调试过程中感觉不太给力、速度慢、功能不稳定,有时进行单步调试都要小等一会,而且多次中断调试后,很容易导致MonoDevelop直接崩溃,无语滴说~ 看来实际开发还得用VS,这个MonoDevelop只能用来做移植性调试用。

是这样滴,我那时候 都给这个折磨的和什么一样,到后期 测试的时候 好像是关闭后,他资源没有释放干净,每次都要重启monodevelop的说...

 回复 引用 查看   
#26楼 2011-09-03 22:30 | Fisherman Cheung      
MonoDevelop的官网没有看到对应CentOS的版本啊
 回复 引用 查看   
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 2099505 qP8wd7Ev7QY=
昵称:钟少
园龄:6年10个月
粉丝:21
关注:1
<2011年7月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

搜索

 
 

常用链接

我的标签

随笔分类

随笔档案

友情链接

最新评论

阅读排行榜

评论排行榜

推荐排行榜