Bootstrap

C# 基于微服务开发框架的设计思路(一)

当我在开发软件的路途中完成了一些项目后,一直在考虑一个问题,怎么才能最少写代码完成最大的工作?当时还没有ORM这个东东,或者说还没有接触到,于是就自己写了一个很初级的ORM,当然,现在看来是很烂了,最起码当时在.net2.0时代,attribute我还不会用,更加不会Emit之类的技术,于是把DAL和ORM合并一起写了。

其实,这种偷懒的思想,每个程序员都会有,我感觉,程序员最强的能力就是总结怎么偷懒,能少写代码就少写。于是,我感觉框架的定义就出来的:

第一,框架完成技术上的封装。当我积累了一定知识和经验后,带了几个新的同事,要我去教,往往要说一些很初级的技术或者插件的使用,例如redis要怎么样操作怎么优化之类的,甚至有多少种类的key;rabbitmq怎么建立通讯,exchange有多少种类型,要怎么配合应用场景使用;log4net怎么使用;mqtt...等等。于是,我就开始了漫长的封装之旅。目前各大开发框架都很强大也很全面,但是学习成本也很高。我希望开发出来的框架,应该自带很多工具和技术封装,降低程序员的学习成本,例如:

SYSHelper :系统中各种常用的工具类,例如映射,路径,Json之类的,这些比较常用就不另外封装,这些都是静态类。

RedisHelper:操作redis的专用工具类,程序员也不用考虑怎么连接到redis,只需要 new RedisHelper(host,port,db)就好了,当然,我设计的是net RedisHelper就好了,然后再app.config文件中定义参数,程序员不需要去考虑怎么连接到redis.里边封装了大量单个操作和批量操作,至于具体是怎么实现的,程序员不需要知道,例如redis.Set(key,hKey,value),redis,Set(key,value),等等,这样,程序员只需要知道自己的应用场景,不需要知道redis操作技术和注意事项。

MQHelper:这里把常用的MQ操作都封装好了,例如发布Publish,和订阅Consume,针对微服务常常互相通讯,特别把这个工具类又进一步封装成:

[MQPublish]

public RValue<T> Insert(T item)

{

        //以下结果三选一

        return item;  //success=true

        return "message"; //success= false 前端显示warn提示信息

        return new Exception(""); //success =false 前端显示error提示信息

}

题外话,这里的RValue是自定义的返回类型格式,是框架自定义的返回结果数据结构,在外部调用

var r = Insert(item);

if(!r)

        return r.ToError();

当r.success==true的时候,就会触发[MQPublish]的发布动作,提取出r.Value的内容,根据当前业务层的应用名称、资源名称、方法名称构造出消息体发布出去。

言归正传,在另外的一个微服务需要接收这个发布消息的时候

[MQConsume("appid","resource","action")]

public RValue<T> MQInsert(T item)

{

        //处理MQ消息

}

这样的设计,大大降低了程序员对插件的使用学习成本,也不需要去调试消息是否存在结构上或者出现异常的情况,因为在发布和接收端,都做了日志处理,只要T这个结构是对的,消息就能准确传达。

apiHelper:定义了微服务之间的通讯方法。例如 var caller = new apiHelper(url,resource,token);

var r = caller.Get<T>("action",parms);

if(!r)

        return r.ToError();

由于框架已经制定了API的请求和返回结果的数据结构,程序员不需要去使用繁琐的httpClient之类的插件,返回的结果也是遵守RValue<T>的结构类型,

其他的工具类不一一举例说明,说白了就是简化插件的使用方法。

第二,制定框架的使用规则。上述工具类的说明,其实已经能够看出一定的规则,例如MQ的通讯数据结构,api请求的数据结构等等,程序员不需要接触到具体的插件,只需要在开发好的工具类上操作,至于怎么记录日志,怎么构造数据结构,那都是工具类内部的事情了。那么问题来了,如果超出了怎么办?简单,那就继续迭代,由架构师去迭代,并且同步制定规则,不能让框架失控了,还要考虑是否有兼容性的问题。

第三,封装一定的业务规则标准。这里和任何技术都没有关系的,是业务的封装。常见的系统开发,分三种,一是单表的操作,例如员工表,部门表这些,都是一些基础数据,没有什么很强的业务性的;二是业务表单的操作,就是主从表的数据结构,常见的销售单、采购单等;三是关联表操作,例如A表和B表之间的关系,是有C表决定的,只是是多对多还是一对多,都不是重要的,别在乎那些细节,一个关联表就解决了,当然也可以是A.ID = B.AID这样直接关联,不在关联表结构范围内。

有了以上三点,就可以制作代码生成器,我现在使用的是CodeSmith,这个工具很好用,当然自己手写也不是事。

一般一个新的项目进入到开发阶段,第一步先做图形化的设计,例如Axure原型设计,PowerDesigner各种流程设计和数据库结构图;第二步,PowerDesigner产生的数据库结构图产生数据库;第三部,通过CodeSmith生产Controller\BLL\DAL\Entity等代码。

这一节,我个人认为,框架设计必须满足以上三点,降低技术学习成本,简化开发代码,制定开发规则,规范业务规则。

后续有空,对微服务框架的各部分进行简单的说明,例如SSO,微服务之间的协调和管理等等。

目前功能性的微服务主要有:

登录验证微服务SSO,权限验证微服务OAuth,系统管理微服务,表达打印微服务,分析报表微服务

ERP业务类的微服务有:

基础数据微服务、销售微服务、采购微服务、仓储微服务、生产微服务、物流微服务,工作流微服务(JAVA的Activity,只是独立部署,并不是本人开发的,应用得不深,满足常规需求)

使用到的中间件:Redis,RabbitMQ

通讯数据格式:Json (使用库Newtonsoft,坚决不使用System.Text.Json反序列化为dynamic时候经常报错)

;