本文讨论如何开发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&", this::sayHello)).withAutoAcl(Boolean.TRUE); } }
|
服务实现:
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 ); } }
|
以上是我们的微服务业务,下面看看整合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"
|
现在,必须激活服务定位器,在服务配置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 } } }
|
现在服务能和服务定位器一起工作了,但是还不能被定位,修改服务模块类保证这个服务能够被定位:
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(); } } } }
|
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}]}}
|
Run a Lagom service standalone with Zookeeper – Co