基于Zookeeper运行独立的Lagom服务

16-09-26 banq
    

本文讨论如何开发Lagom微服务,Lagom是一个集成了微服务、RESTful、CQRS、EventSoucring、Reactive编程等最潮概念的开发框架。介绍见:这里

微服务是必须结合服务定位器,在开发环境,Lagom的插件提供了out of box之外的服务定位器,在独立部署运行时,需要使用Zookeeper作为服务定位器。

下面展示如何使用Zookeeper作为服务定位注册器,然后打包运行一个Lagom微服务。

服务接口:

import com.lightbend.lagom.javadsl.api.Descriptor;
import com.lightbend.lagom.javadsl.api.Service;
import com.lightbend.lagom.javadsl.api.ServiceCall;
 
import static com.lightbend.lagom.javadsl.api.Service.named;
import static com.lightbend.lagom.javadsl.api.transport.Method.POST;
 
public interface HelloWorldService extends Service {
 
    ServiceCall<String, String> sayHello();
 
    @Override
    default Descriptor descriptor() {
 
        return named("helloWorld").withCalls(Service.restCall(POST, "/msg&amp", this::sayHello)).withAutoAcl(Boolean.TRUE);
    }
}
<p>

服务实现:

import com.lightbend.lagom.javadsl.api.ServiceCall;
 
import static java.util.concurrent.CompletableFuture.completedFuture;
 
public class HelloWorldServiceImpl implements HelloWorldService {
 
    @Override
    public ServiceCall<String, String> sayHello() {
        return request -> completedFuture("Hello" + request );
    }
}
<p>

以上是我们的微服务业务,下面看看整合Zookeeper:

首先,加入zookeeper的实现到lagom服务中,在本地建立lagom-zookeeper-service-locator项目,在github上已经有这个项目模板,直接下载:

git clone https://github.com/jboner/lagom-service-locator-zookeeper.git

发布在本地:

> sbt publishLocal

一旦被发布后,我们得增加这个项目作为服务的依赖,打开build.sbt,加入下面一行:

 libraryDependencies in ThisBuild += "com.lightbend.lagom" % "lagom-service-locator-zookeeper_2.11" % "1.0.0-SNAPSHOT"
<p>

现在,必须激活服务定位器,在服务配置application.conf中定义模块类,如何访问服务定位器zookeeper实例:

lagom {
  discovery {
    zookeeper {
      server-hostname = "127.0.0.1"   # hostname or IP-address for the ZooKeeper server
      server-port     = 2181          # port for the ZooKeeper server
      uri-scheme      = "http"        # for example: http or https
      routing-policy  = "round-robin" # valid routing policies: first, random, round-robin
    }
  }
}
<p>

现在服务能和服务定位器一起工作了,但是还不能被定位,修改服务模块类保证这个服务能够被定位:

public class HelloWorldServiceModule extends AbstractModule implements ServiceGuiceSupport {
 
    private Environment environment;
 
    @Inject
    public HelloWorldServiceModule(Environment environment, Configuration configuration) {
        this.environment = environment;
    }
 
    @Override
    protected void configure() {
 
        bindServices(serviceBinding(HelloWorldService.class, HelloWorldServiceImpl.class));
 
        if (environment.mode() == Mode.Prod()) {
 
            try {
                ZooKeeperServiceRegistry registry = new ZooKeeperServiceRegistry(
                        ZooKeeperServiceLocator.zkUri(),
                        ZooKeeperServiceLocator.zkServicesPath());
                registry.start();
 
                // create the service instance for the service discovery
                // needs to be held on to to be able to unregister the service on shutdown
                ServiceInstance<String> serviceInstance = ServiceInstance.<String>builder()
                        .name("helloWorld")
                        .id("helloWorldId")
                        .address("localhost")
                        .port(8080)
                        .uriSpec(new UriSpec("{scheme}://{serviceAddress}:{servicePort}"))
                        .build();
 
                // register the service
                registry.register(serviceInstance);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

<p>

id参数是指向微服务的标识,name是微服务名称。

现在你的服务能够在独立方式下运行,下面看看如何打包并运行服务:

从sbt控制台打包:

> project helloWorld-imp

运行下面命令:

> dist

以独立方式启动服务:

/helloworld/helloWorld-impl/target/universal/

生成压缩包:helloworldimpl-[current_version].zip

其中包含所有元素。

解压:

unzip helloworldimpl-1.0-SNAPSHOT.zip

运行bin目录下脚本:

./helloworldimpl-1.0-SNAPSHOT/bin/helloworldimpl

现在你的Lagom服务已经启动。

通过zookeeper客户端zkCli.sh访问,通过下面命令获得所有服务信息:

get /lagom/services/helloWorld/helloWorldId

会得到:

{"name":"helloWorld","id":"helloWorldId","address":"localhost",
"port":8080,"sslPort":null,"payload":null,
"registrationTimeUTC":1474744298139,"serviceType":"DYNAMIC",
"uriSpec":{"parts":[{"value":"scheme","variable":true},
{"value":"://","variable":false},
{"value":"serviceAddress","variable":true},
{"value":":","variable":false},{"value":"servicePort","variable":true}]}}
<p>

Run a Lagom service standalone with Zookeeper – Co