关于clojure:我可以让lein ring server-headless在特定的servlet上下文上运行吗?

Can I make lein ring server-headless run on a specific servlet context?

我有一个Ring应用程序,它可以作为uberwar部署到生产环境; myservice.war。在生产中,WAR文件被扔到Jetty中,并在其名称

后的上下文中运行

1
2
3
$ curl -i -X GET http://myservice.qa1.example.com:8080/myservice/healthz
HTTP/1.1 200 OK
...

当我通过lein ring在本地运行时,我需要它在相同的上下文中运行; myservice。

1
2
3
4
$lein ring server-headless
2015-10-14 14:04:03,457  level=INFO [main] Server:271 - jetty-7.6.13.v20130916
2015-10-14 14:04:03,482  level=INFO [main] AbstractConnector:338 - Started [email protected]:10313
Started server on port 10313

但相同的卷曲会在本地将所有404传递给我。

1
2
3
$ curl -i -X GET http://localhost:10313/myservice/healthz
HTTP/1.1 404 Not Found
...

lein环事物将其部署到根上下文中。

1
2
3
$ curl -i -X GET http://localhost:10313/healthz
HTTP/1.1 200 OK
...

那是怎么回事?如何引导lein环部署到我选择的上下文名称中?我需要curl -i -X GET http://localhost:10313/myservice/healthz在lein ring

上工作


解决此问题的一种方法是为您的应用创建第二组(独立)路由。您还为独立案例创建第二个处理程序。然后,您可以使用Leiningen配置文件为独立案例和uberwar案例指定不同的处理程序。独立运行应用程序时使用默认配置文件。创建uberwar时使用:uberjar配置文件。结果,当战争部署到容器中时,您的独立处理程序将与lein ring server-headless一起使用,而常规处理程序将被使用。

创建第二组路由不需要太多其他代码。您可以将现有路线package在您选择的上下文中。假设以下是您的路由和环形处理程序:

1
2
3
4
5
6
(defroutes app-routes
  (GET"/healthz" []"Hello World")
  (route/not-found"Not Found"))

(def app
  (wrap-defaults app-routes site-defaults))

独立案例的其他路由和处理程序如下所示:

1
2
3
4
5
6
(defroutes standalone-routes
  (context"/myservice" req app-routes)
  (route/not-found"Not Found"))

(def standalone-app
  (wrap-defaults standalone-routes site-defaults))

现在,进入project.clj中的lein-ring配置。我们希望默认的环形处理程序指向standalone-app。 uberwar的铃声处理程序应指向appproject.clj中的项目映射中的:ring条目应如下所示(根据您的实际名称空间进行调整):

1
:ring {:handler myservice.handler/standalone-app}

此外,将以下内容合并到project.clj中的:profiles映射中:

1
:uberjar {:ring {:handler myservice.handler/app}}

请确保使用最新版本的lein-ring插件。 0.9.7版本对我有用。较早的版本(如0.8.3)无法正常运行,因为它们在运行uberwar任务时未使用:uberjar配置文件。

如果您执行所有这些操作,并且假设您的war文件名为myservice.war,则无论您的应用程序是使用lein ring server-headless启动还是war文件已部署在Jetty中,URI的上下文部分都将是相同的。

1
$ curl http://localhost:[port]/myservice/healthz