引言
从去年就觉得云计算是一个必然趋势,现在这个趋势已经非常明显了。而微软也在不久前刚刚坐上云江湖第一把交椅,业绩超过SalesForce和Amazon成为全球第一。
本人上个月参加了公司的一次活动,有一系列Azure的课程。最后老板号召大家,learn the cloud, feel the cloud, live the cloud...我深刻体会到认真学习Azure的必要性。那该怎么学呢?就买本书翻翻,然后看些培训的视频就可以了吗?当然不行!会一样东西,必须有一定的深度才有价值。要想深入学习,必须要动手!
于是我找出了我几年前开发的一个中国象棋程序。这个象棋有个AI的算法,可以人机对弈。把这个搬上Azure,好像不错。但如果仅仅是提供一个在线的象棋游戏程序,那远远不够。需要一个远景,那就是把天空象棋做成国内AI智商最高的,可人机对弈或人人对弈,提供比赛研究、赛事直播等高级功能,即一个强大的象棋社交网络平台!要做成这个平台,可以用到Azure绝大部分的特性和优势:
- Azure托管服务:提供AI计算资源。可配置的自动伸缩和高可用性,支持几乎无限的并发。并可通过增加计算资源,提高AI智能
- Azure数据存储:保存系统日志,历史棋局,数据库等各种数据
- Azure网站:象棋社交平台门户
- Media Services和CDN:赛事直播、媒体服务
- Mobile Services:构建和承载手机和平板上的天空象棋的后端
- SQL Azure:用户数据,AI分析数据等
- HDInsight:数据分析,提高AI智能
在接下来的一段时间,我将通过天空象棋的功能实现,逐一学习Azure的功能、特性和开发方法。并将一些学习心得在此分享,欢迎交流、讨论。
开发环境
主要有Visual Studio,SDK, SQL Server和Azure订阅。
- 推荐使用Visual Studio 2013 Update 3或者Update 4。使用“Web平台安装程序”安装“Microsoft Azure SDK – 2.5 for Visual Studio 2013”
- Microsoft Azure订阅(可申请免费试用或者使用MSDN订阅赠送的额度)
- 后面需要管理、开发SQL Azure,安装SQL Server 2012 SP2或者SQL Server 2014
开发SkyChess云服务
SkyChess有一个AI算法,通过传递棋局状态,可返回建议的走法。这次的任务,是将该算法发布到云端,使用Azure托管服务,该托管服务运行在PaaS层面。
Azure托管服务主要有“Web角色(Web Role)”和“辅助角色(Worker Role)”。Web角色一般用于网站、Web Service等使用HTTP协议的服务;辅助角色不限于HTTP协议,可通过内部通信和其他角色互动。SkyChess的AI算法适合发布为Web角色。
新建解决方案时选择Cloud->Azure云服务,然后在云服务角色选择窗口中选择“WCF服务Web角色”,修改名称为“SkyChess.WebRole”。
创建完成后有两个项目,一个是云服务本身的项目“SkyChess.CloudService”,另一个是WCF项目“SkyChess.WebRole”。这里的WCF项目跟普通的WCF项目并没有大的不同,只是引用了Azure的 几个程序集。
在SkyChess.WebRole项目中引用自己的两个程序集,SkyChess.ChessCommon和SkyChess.ChessAI。定义ServiceContract如下:
[ServiceContract] public interface IChessAdvisor { [OperationContract] ChessMoveSearchEventArgs SuggestChessMove(byte[] gameData, int currentSide); }
- 参数gameData:一个长度为90的字节数组定义棋局状态。棋盘每行9个落子点,共10行。从左上角到右下角共90个落子点分别用90个byte表示状态。没有棋子的地方为0,其余按如下表:
棋子 | 棋盘顶部方 | 棋盘底部方 |
兵 | 1 | 129 |
炮 | 2 | 130 |
马 | 3 | 131 |
车 | 4 | 132 |
相 | 5 | 133 |
士 | 6 | 134 |
将 | 7 | 135 |
- 参数currentSide:当前是哪一方走棋,1表示棋盘底部的一方走棋,否则为棋盘顶部的一方走棋
类ChessAdviceService实现该接口时调用ChessAI程序集里的ChessMoveProvider获取走法。ChessMoveProvider有多个子类,实现不同的算法。ChessAdviceService如果使用某个固定的子类,则不便于服务部署后调整,应该将算法类型配置在云服务端。
一般的WCF项目我们可以把配置信息写在Web.Config中,但这里不适合这样做。因为云服务会被部署到多个虚拟机上,改Web.Config中的配置需要登陆到各个虚拟机就行修改,比较麻烦。
最佳的做法是使用云服务角色的设置功能。打开“SkyChess.WebRole”的属性窗口,在设置选项卡中可以看到如下内容:
图中三个设置,分别定义了子类的名称,两种算法的配置。设置完成后,可在ServiceDefinition.csdef和ServiceConfiguration.Cloud.cscfg中看到设置的定义和配置值。
在ChessAdviceService调用SDK的Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetConfigurationSettingValue方法获取设置值。
Azure中配置服务的伸缩性和高可用性是非常方便的。发布后可在Azure的管理页面配置,发布前可在Visual Studio中配置。在“SkyChess.WebRole”属性窗口配置页,设置实例计数为“2”,VM大小为“Medium”。
调试云服务
编译通过后选择“SkyChess.CloudService”进行调试,可以看到调试的服务地址为http://localhost:81。不同于WCF项目SkyChess.WebRole设置的端口。
从Windows系统托盘打开运行中的Azure模拟器,可以看到当前模拟的实例。
简易象棋客户端
在象棋客户端WPF项目ChineseChessExpress中引用http://localhost:81位置的云服务。并定义一个ChessMoveProvider的子类SkyChessMoveProvider,在重写的SearchChessMove方法中调用云服务获取推荐走法。
public override ChessMoveSearchEventArgs SearchChessMove(Game game, ChessSide currentSide) { byte[,] gd = game.GetGameData(); byte[] gameData = new byte[90]; for (int y = 0; y < 10; y++) for (int x = 0; x < 9; x++) gameData[y * 9 + x] = gd[y, x]; int side = 0; if (currentSide == ChessSide.Bottom) side = 1; ChessMoveSearchEventArgs args = advisor.SuggestChessMove(gameData, side); return args; }
在主界面中设置SkyChessMoveProvider作为机器人的算法。
SkyChessMoveProvider scp = new SkyChessMoveProvider(); MainChessBoard.ChessGame.SetChessRobot(ChessSide.Top, scp);
同时启动SkyChess.CloudService和ChineseChessExpress两个项目可进行调试。
发布云服务
Visual Studio中选择发布SkyChess.CloudService云服务,经过简单设置后即可进行发布。
其中环境选项有Production和Staging两种。Production为生产环境,Staging为过渡环节。在实际应用中,一般先将服务发布至过渡环境,通过过渡环境的访问地址进行测试。如果没有问题,再将两个环境的版本进行切换。切换后如发现问题,还可以马上切换回原来的版本。
Visual Studio进行发布时,可以查看整个发布的过程。
SkyChess云服务发布的地址是:http://skychess.cloudapp.net/
联机在线调试
将ChineseChessExpress中app.config访问端点的地址改为“http://skychess.cloudapp.net/ChessAdviceService.svc”。再运行象棋客户端进行调试。
底部红方为人为控制,顶部黑方是机器人通过调用SkyChess云服务进行控制的。目前配置的算法为AlphaBeta四级,相当于入门水平。
在Azure的管理页面,可查看云服务的调用情况。