您的位置:首页 > 编程语言 > Java开发

在项目中如何使用ja-micro框架(二)

2017-06-16 14:10 344 查看
在第一节中,我介绍了如何在自己的工程中引入ja-micro。接下来介绍一下ja-micro启动的关键点吧。

https://github.com/Sixt/ja-micro/wiki中,有两个视频是介绍如何进行自己的微服务开发的,示例是用gradle工具对工程进行编译、运行的,示例中开发用的IDE是intelliJ。很不幸,这两个我都不熟悉,所以刚看两个视频的时候,走了很多弯路。我先是一步步照着视频中的示例来操作。但是不知道是什么原因,在我自己的intelliJ中,总是安装不上能够支持proto3的插件,导致后面完全没法继续。

经常多次钻研视频中的做法,我注意到了一个细节。示例中启动测试工程的时候,并非自己在自己的类中写一个main方法来启动,程序启动加载的main方法,在JettyServiceBase
类中,程序启动时,还需要向main方法传递一些运行时需要的参数,分别是:-serviceAddress、-servicePort、-logLevel、-registryServer、-registry这些参数的作用分别如下:

-serviceAddress:程序启动时,向微服务管理注册的自己的服务地址,通常是127.0.0.1;

-servicePort:是程序运行时占用的端口号;

-logLevel:是程序运行时的日志记录的等级,这个很好理解,开发阶段通常用DEBUG,上线后通常设置为INFO;

-registryServer:是微服务管理平台的地址,如果程序向本的consul注册自己,则该值通常为:127.0.0.1:8500,当然你也可以向任意一个可以访问到的微服务管理平台注册,只要程序所在的机器能够访问到行。

-registry:微服务管理平台名称,我用的是consul,所以在我的程序中,这个参数的值固定为consul。

仅向JettyServiceBase.main传递上述参数,是不足以保证自己的微服务程序顺利启动的。为什么呢?很简单,还没有写一行自己的代码,都没有自己的微服务程序,肯定无法启动了。

在微服务中,必须有自己的服务名称、还需要有自己的handler,否则怎么让别人来使用你提供的服务。在ja-micro框架中,如何编写自己的服务名和handler呢?

jettyServiceBase中的代码不长,很快就能看完。它做的主要工作是先扫描要加载的信息,比如符合要求的Service、Handler类,然后初始化配置信息,最后启动一个Jetty容器。

要让自己的程序run起来,最重要的是写好Service类和至少一个Handler类。首先,得在自己的工程中编写一个自己的Service类,其要求如下:

1、该Service类,必须继承AbstractService
这个虚拟类;

2、在该Service类中,必须将类注解为OrangeMicroservice;

3、不准写多于一个继承AbstractService的类。

例如:

@OrangeMicroservice
public class ServiceEntryPoint extends AbstractService {
private static Logger logger = LoggerFactory.getLogger(ServiceEntryPoint.class);

@Override
public void registerMethodHandlers() {
getServiceProperties().setServiceName("base.monitor");
}

@Override
public void displayHelp(PrintStream arg0) {
// TODO Auto-generated method stub

}

@Override
public void bootstrapComplete() throws InterruptedException {
// Start a messaging consumer for the default inbox.
//		ConsumerFactory consumerFactory = injector.getInstance(ConsumerFactory.class);
//		consumerFactory.defaultInboxConsumer(new DiscardFailedMessages());
//		injector.getInstance(SshHandler.class);

//		this.serviceProperties.setServiceName("base_monitor");
super.bootstrapComplete();
}


很奇怪吧?为什么继承AbstractService的类只能有一个,不允许有多个?因为,这是自己微服务的入口,只允许定义一个。当JettyServiceBase在扫描时发现AbstractService的子类超过一个,程序就抛异常退出。

在自己定义的AbstractService子类中,只需要实现它的所有方法即可,除了在bootstrapComplete方法中必须调用一下super.bootstrapComplete();其它你什么都不必做,就算完成了自己子类的编写。

事实上,当你完成了AbstractService子类的开发后,微服务程序已经可以run起来了。这是个服务里面是没有提供可以访问的方法而已。

自己做的微服务,总得有东西给别用才行。那么,就开始写自己的handler吧。

对于handler类也是有要求的:

1、必须继承ServiceMethodHandler接口;

2、选项是在handler类上面加上注解RpcHandler,为什么说是选项呢,因为注解不是必须的,但如何不用注解,就必须在AbstractService类,手工调用registerMethodHandlerFor方法对handler进行注册,毫无疑问,在handler类中增加一个注解是非常省心的事。

@RpcHandler("monitor.SshGetLinuxMemInfo")
public class SshGetLinuxMemInfo implements ServiceMethodHandler<REQ, RES> {
向上面一样来定义这个handler类即可,而类中实现的handleRequest方法,则是提供给别人访问的服务实体。类中用到的REQ和REST是两个泛型。ServiceMethodHandler接口定义如下 :

public interface ServiceMethodHandler<REQ extends Message, RES extends Message> {

RES handleRequest(REQ request, OrangeContext ctx) throws RpcCallException;

}


Message是谷歌probobuf中定义的接口,它的继承图如下示:



事实上,在我的handler中,ServiceMethodHandler中的两个泛型都是GeneratedMessageV3的子类,它们是我的handler的出参和入参。这两个泛型类是如何定义出来的,这就不得不提到谷歌的protobuf了。在下一节中,我再介绍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息