Heya everyone,

great to see a lot of people again and even new faces in Frankfurt today! As 
there was some interest in the deployment stuff, here are some semi-random 
notes from the train ride back to get you started.

TL;DR: Lots of code snippets and config

Used software
- Service discovery https://www.consul.io/ <https://www.consul.io/>
- Process management https://www.nomadproject.io/ <https://www.nomadproject.io/>
- Traffik routing https://traefik.io/ <https://traefik.io/>

All can be installed for messing around through homebrew or downloaded as 
single binaries from their respective pages.

Initial launch consul / nomad
Nomad and consul can be run in dev mode locally:

$ consul agent -dev
$ nomad agent -dev

per default the web UI is available on port 8500 (consul) and 4646 (nomad)

Integrating consul in your WOApp
We're using the consul-client library, which can be found at 
https://mvnrepository.com/artifact/com.orbitz.consul/consul-client/1.3.3 
<https://mvnrepository.com/artifact/com.orbitz.consul/consul-client/1.3.3> 
Then the code comes down to (roughly):

final Consul.Builder builder = 
Consul.builder().withHostAndPort(HostAndPort.fromParts("localhost", 8500));
final Consul consul = builder.build();
final ConsulAgent consulAgentClient = consul.agentClient();
final WOApplication application = WOApplication.application();
final String serviceID = "someUniqueValue"; // we use host + appname + port to 
build this
final ImmutableRegCheck ttlCheck = ImmutableRegCheck.builder()
                .ttl("5s")
                .deregisterCriticalServiceAfter("60s")
                .build();
final Registration registration = ImmutableRegistration.builder()
                .port(application.getPort())
                .id(serviceID)
                .address(application.getHost())
                .name(application.name())
                .addTags("WebObjectsApp", NSBundle.mainBundle().name())
                .addChecks(ttlCheck)
                .build();

consulAgentClient.register(registration);
consulAgentClient.pass(serviceID);

After this happened, you need to regularly "check in" with consul (see the 
ttlCheck.ttl() argument), otherwise the app will be declared down. After the 
deregister time (next line) it will completely be removed from the system (to 
not leave around too many zombie entries). You can check in by regularly 
calling (for example in a separate thread):

consulAgentClient.pass(serviceID);

You should then see your service popup in the service tab of consul ✅ (note 
that the web UI has a different look than in my presentation as my demo system 
still uses an older version).

Using consul-template to generate a traefik configuration and launching traefik
Consul-template is part of consul (in homebrew) and can be used to dynamically 
generate the configuration. An example could look like this (called 
traefik-ctmpl): 

[entryPoints]
        [entryPoints.http]
                address = ":10080"
        [entryPoints.traefik]
                address = ":10081"

[api]
        entryPoint = "traefik"
        dashboard = true
        debug = true

[file]

[backends]
{{range services}}{{if .Tags | contains "WebObjectsApp" }}
        [backends.wobackend-{{.Name}}]
                [backends.wobackend-{{.Name}}.loadBalancer]
                        method = "drr"
                [backends.wobackend-{{.Name}}.buffering]
                        maxRequestBodyBytes = 10485760
                        memRequestBodyBytes = 2097152
                        maxResponseBodyBytes = 10485760
                        memResponseBodyBytes = 2097152
                        retryExpression = "IsNetworkError() && Attempts() <= 2"
{{range service .Name}}
                [backends.wobackend-{{.Name}}.servers.{{.Node | replaceAll "." 
"-"}}-{{.Port}}]
                        url = "http://{{.NodeAddress}}:{{.Port}}";
                        weight = 10
{{end}}{{end}}{{end}}

[frontends]
{{range services}}{{if .Tags | contains "WebObjectsApp" }}
        [frontends.wofrontend-{{.Name}}]
                backend = "wobackend-{{.Name}}"
                passHostHeader = true
                [frontends.wofrontend-{{.Name}}.routes.route-woa]
                        rule = "PathPrefix: /cgi-bin/WebObjects/{{.Name}}.woa/"
{{end}}{{end}}

This will configure the traefik http traffic on port 10080 and service UI an 
10081. There is also some basic configuration to forward headers to the 
application, have large request / response buffers and a 3-try retry mechanism. 
You now run consul-template and traefik from the resulting configuration.

$ consul-template -template traefik-ctmpl:traefik.toml # continuously generate 
traefik.toml using traefik-ctmpl
$ traefik -accesslog

Congratulations
All apps you launch like this, are now available at 
http://localhost:10080/cgi-bin/WebObjects/ApplicationName.woa/ 
<http://localhost:10080/cgi-bin/WebObjects/ApplicationName.woa/> :-)

Integrating your WOApp into Nomad
For this you'll need the 2020 WO-Day-Ference access pass ;-) At least currently 
we haven't finished this part but you can follow the guide at 
https://www.nomadproject.io/intro/getting-started/jobs.html 
<https://www.nomadproject.io/intro/getting-started/jobs.html> to get a basic 
idea how to schedule and run your applications in Nomad. All that is really 
required for WOApps, is some additional glue, to get the current hostname, 
extract the port from the consul-provided server.port java property and feed it 
into the correct WO* parameters (in addition to other required / desired 
parameters for logging and running in the proper standalone mode).

If you made it here, these notes hopefully are of some interest to you and 
maybe even helpful. Feel free to continue here on the mailing list or contact 
me for any further questions!

Greetings
Dennis

PS: It seems that session stickiness currently unfortunately is only supported 
through cookies, as otherwise traefik and the application would need a somewhat 
(same) deeper understanding of the URL scheme to properly generate content and 
links or traefik would have to inspect the content deeper. 
--






-----------------------------------------------------
Dennis Bliefernicht • Head of Backend Development
T +49 40 357 3001 62
dennis.blieferni...@xyrality.com <mailto:dennis.blieferni...@xyrality.com>

XYRALITY GmbH • Friedensallee 290 • 22763 Hamburg
www.xyrality.com <http://www.xyrality.com/>
Registergericht: Hamburg HRB 115332
Geschäftsführer: Sven Ossenbrüggen
-----------------------------------------------------

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      (Webobjects-dev@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to