microservice:轻量级微服务框架,支持注册中心、RPC、负载均衡及Cannon WEB容器

微服务:支持注册中心,远程过程调用,负载均衡,内置一个Cannon WEB容器,自定义codecs、异常处理器、响应报文,零侵入业务

分支1Tags0
文件最后提交记录最后更新时间
0.53.41 年前
0.53.41 年前
0.53.41 年前
0.53.41 年前
0.53.41 年前
0.53.41 年前
0.53.41 年前
INIT1 年前
INIT1 年前
0.53.41 年前
0.53.41 年前
0.53.41 年前

microservice

介绍

微服务:支持注册中心,远程过程调用,负载均衡,内置一个Cannon WEB容器,自定义codecs、异常处理器、响应报文,零侵入业务

软件架构

软件架构说明 软件包图

源码目录

├── bin
├── cjpm.lock
├── cjpm.toml
├── docs
│   └── package.jpg
├── examples
│   ├── boot
│   │   └── microboot.cj
│   └── unit
│       ├── example_endpoint.cj
│       ├── example_properties.cj
│       ├── example_simple_withoutproperties.cj
│       └── example_webserver_cangjielib.cj
├── full.json
├── LICENSE
├── README.md
├── resources
│   └── application.properties
├── src
│   ├── common
│   │   └── common.cj
│   ├── config
│   │   ├── constant.cj
│   │   ├── properties.cj
│   │   └── resourcefile.cj
│   ├── exception
│   │   ├── connectionexception.cj
│   │   ├── exceptionclassify.cj
│   │   ├── microserviceexception.cj
│   │   ├── nomappingfindexception.cj
│   │   ├── sizetoobigexception.cj
│   │   ├── systemexception.cj
│   │   └── unsupportexception.cj
│   ├── main.cj
│   ├── registry
│   │   ├── config.cj
│   │   ├── consul.cj
│   │   ├── discovery.cj
│   │   ├── etcd.cj
│   │   ├── eureka.cj
│   │   ├── nacos.cj
│   │   ├── registry.cj
│   │   ├── registrymethod.cj
│   │   └── zookeeper.cj
│   ├── resttemplate
│   │   ├── eurekaclient.cj
│   │   ├── interceptor.cj
│   │   ├── loadbalance.cj
│   │   ├── refer.cj
│   │   ├── resttemplate.cj
│   │   └── roundrobbin.cj
│   ├── trace
│   │   ├── logger.cj
│   │   ├── trace.cj
│   │   └── uuid.cj
│   └── web
│       ├── application.cj
│       ├── codecs
│       │   ├── codecs.cj
│       │   ├── jsoncodecs.cj
│       │   ├── messagecodecs.cj
│       │   ├── multipartcodecs.cj
│       │   ├── requestjsonobject.cj
│       │   ├── responsejsonobject.cj
│       │   ├── urlencodedcodecs.cj
│       │   └── xmlcodecs.cj
│       ├── handler
│       │   ├── defaultexceptionhandler.cj
│       │   ├── exceptionhandler.cj
│       │   └── globalexceptionhandler.cj
│       ├── http11
│       │   ├── cookie.cj
│       │   ├── cookies.cj
│       │   ├── defaultdispatcher.cj
│       │   ├── dispatcher.cj
│       │   ├── header.cj
│       │   ├── headers.cj
│       │   ├── http11dataprocessor.cj
│       │   ├── http11dataprocessorfactory.cj
│       │   ├── http11method.cj
│       │   ├── http11protocol.cj
│       │   ├── http11req.cj
│       │   ├── http11res.cj
│       │   ├── httpcommon.cj
│       │   ├── keepalive.cj
│       │   ├── pair.cj
│       │   └── params.cj
│       ├── limit
│       │   └── limit.cj
│       ├── microbootapplication.cj
│       ├── security
│       │   ├── crossorigin.cj
│       │   └── xss.cj
│       ├── server
│       │   ├── adapter.cj
│       │   ├── cannonserver.cj
│       │   ├── defaultrouter.cj
│       │   ├── filter
│       │   │   ├── filterchain.cj
│       │   │   └── filter.cj
│       │   ├── fitlerrouter.cj
│       │   ├── reqres
│       │   │   ├── request.cj
│       │   │   └── response.cj
│       │   ├── router.cj
│       │   └── servlet.cj
│       ├── socket
│       │   ├── acceptor.cj
│       │   ├── dataprocess.cj
│       │   ├── endpoint.cj
│       │   ├── eventlistener.cj
│       │   ├── eventlistenerhandler.cj
│       │   ├── socketevent.cj
│       │   ├── sockethandler.cj
│       │   └── socketwrapper.cj
│       └── web.cj
└── test
    ├── HLT
    │   └── hlt01_serve.cj
    ├── LLT
    │   └── llt_01_webserver.cj
    └── UT
        ├── register.json
        ├── ut01_registry.cj
        ├── ut02_string.cj
        ├── ut03_heartbeat.cj
        ├── ut04_discovery.cj
        └── ut05_exception.cj
  • bin 第三方辅助程序,如注册中心
  • doc 库的设计文档、提案、库的使用文档、LLT 覆盖率报告
  • src 库源码目录
  • resources 配置文件目录
  • examples 案例目录
  • test 测试用例目录

安装教程

  1. cpm build

配置文件使用说明 (resources/application.properties)

server.name=hello                                               //服务名,用于注册和发现服务
server.port=8080                                                //网络端口
server.registryAddress=http://localhost:8761/eureka/apps        //微服务注册中心地址
server.maxConnections=2000                                      //支持最大连接数
server.acceptCount=200                                          //接受数
server.uriEncoding=UTF-8                                        //编码
server.maxHttpHeaderSize=8192                                   //http包头最大长度限制
server.maxHttpBodySize=81920                                    //http包体最大长度限制
server.connectionTimeout=3000                                   //连接超时时间
server.logging.level=info                                       //日志级别

使用方式一 MicroBoot(自动装配:启动读取properties配置文件) 推荐!

  1. MicroBootApplication //定义启动类
  2. Auto Defined ExceptionHandler //定义异常处理(可选)
  3. RestTemplate //定义客户端远程过程调用器(支持负载均衡器)
  4. Url Router //定义路由器规则
class BootServlet <: IServlet{
    public func service(req:HttpServletRequest,res:HttpServletResponse){
        println("BootServlet called")
        var root = ResponseJsonObject()
        root.put("code", 0)
        root.put("msg", "success")
        var data = ResponseJsonObject()
        data.put("uid","123456")
        root.put("data",data)
        res.setBody(root)
    }
} 

func microbootServer(){
    let micro = MicroBootApplication()
    micro.getRouter().get("/fo", BootServlet())
    micro.run()

    //下面代码发起一次调用测试
    println("do resttemplate call response="+micro.getRestTemplate().getForEntity("http://hello/fo",""))
}
main(): Unit{
    println("hello microbootServer")
    microbootServer()
    sleep(86400*365*Duration.second)
}

使用方式二 ManualServer(手工装配:不读取properties配置文件)

  1. Application //定义应用服务
  2. Registry //定义注册中心
  3. RestTemplate //定义客户端远程过程调用器(支持负载均衡器)
  4. Url Router //定义路由器规则
class DemoServlet <: IServlet{
    public func service(req:HttpServletRequest,res:HttpServletResponse){
        res.setBody("it is only a demo")
    }
} 

func manualServer(){
    var cfg = Config()
    cfg.url = "http://localhost:8761/eureka/apps"
    let rgs = EurekaRegistry().config(cfg)
    let ws = Application().name("hello").port(8000).registry(rgs);
    ws.getRouter().get("/fo", DemoServlet())
    ws.run()

    //下面代码发起一次调用测试
    spawn { => 
      sleep(10*Duration.second)
      let resttemplate = RestTemplate(rgs)
      println(resttemplate.getForEntity("http://hello/fo",""))
    }
}

main(): Unit{
    println("hello manualServer")
    manualServer()
    sleep(86400*365*Duration.second)
}

使用方式三 ExternServer(使用外部WEB容器:仅使用本库提供的注册发现以及远程过程调用功能,这里是演示使用仓颉内置的web server)

func externServer(){
    var cfg = Config()
    cfg.url = "http://localhost:8761/eureka/apps"
    let rgs = EurekaRegistry().config(cfg)
    let resttemplate = RestTemplate(rgs)
    var a = FuncHandler(
        {
            context => context.responseBuilder.body("hello world")
        }
    )

    let ws = WebServer(8000, 3*Duration.second, 5*Duration.second)
    .setAppName("hello")
    .handle("/fo",a)
    .registry(rgs);
    ws.start()

    //下面代码发起一次调用测试
    spawn { => 
      Common.sleeps(6*Duration.second)
      println(resttemplate.getForEntity("http://hello/fo",""))
    }

}   

main(): Unit{
    println("hello externServer")
    externServer()
    sleep(86400*365*Duration.second)
}
    

基本用法

1. 实现服务处理器

class BootServlet <: IServlet{
    public func service(req:HttpServletRequest,res:HttpServletResponse){
    }
} 

2. 配置路由分发

micro.getRouter().get("/fo", BootServlet())

3. 获取path参数

若参数名为a,b,则 req.getParameter("a"), req.getParameter("b")

4. 获取header参数

若参数名为NAME,则 req.getAttribute("NAME")

5. 获取post参数

var input: RequestJsonObject = RequestJsonObject(req.getBodyObject())
var str = input.getString("name")
var i = input.getInt32("age")
或者 
var o  = req.getBodyObject() as JsonObject, 其中o为JsonObject 对象,使用仓颉官方库解析json

6. 设置header参数

res.setHeader("header01", "value01")

7. 获取cookie参数

若参数名为CookieName,则 req.getCookie("CookieName"),返回对象为Cookie类

8. 设置cookie参数

若Cookie类对象为c,则 res.addCookie(c)

9. 远程过程调用

public func getForEntity(url: String, data: String): String
public func getForEntity(url: String, data: String, headers: HashMap<String,String>): String
举例:micro.getRestTemplate().getForEntity("http://hello/fo","a=123&b=456")

10. 自定义全局异常处理


class AutodefinedGlobalHandler <: IExceptionHandler{
  public func handle(req: HttpServletRequest, res: HttpServletResponse, e: Exception): Unit{
     res.setBody(e.message)
     res.setStatus(500)
  }
}

GlobalExceptionHandler.setDefaultExceptionHandler(AutodefinedGlobalHandler())

11. 自定义特定类型异常处理


class NoMappingHandler <: IExceptionHandler{
  public func handle(req: HttpServletRequest, res: HttpServletResponse, e: Exception): Unit{
     res.setBody("No URL Match")
     res.setStatus(500)
  }
}

GlobalExceptionHandler.add(ExceptionClassify.NOMAPPING_FIND_EXCEPTION, NoMappingHandler())

12. 自定义Filter


public class MyFilter <: IFilter{
    public func doFilter(req: HttpServletRequest, res: HttpServletResponse, filterChain: FilterChain): Unit{
        filterChain.doFilter(req, res)   
    }
}

FilterChain.addFilterToHead(MyFilter())

13. 设置跨域

var crossOrigin = CrossOriginFilter()
crossOrigin.add("/api/test")
FilterChain.addFilterToHead(crossOrigin)

其他问题?

  1. 如何启动一个注册中心?
    java -jar -Deureka.server.response-cache-update-interval-ms=1 eureka-server.jar
  1. 可执行文件和resources/application.properties位置?
    可执行文件和resources同一级目录;application.properties放在目录resources内

项目介绍

微服务:支持注册中心,远程过程调用,负载均衡,内置一个Cannon WEB容器,自定义codecs、异常处理器、响应报文,零侵入业务

定制我的领域