Project

General

Profile

How to Gateway » History » Version 15

Henning Blohm, 20.02.2020 21:37

1 2 Henning Blohm
h1. How to configure and use the Gateway module
2
3 12 Henning Blohm
The Gateway module implements a "zero-downtime-upgrade" feature in Z2. Specifically, it uses the worker process management of Z2 in conjunction with an intermediate reverse proxy style Web handler to implement the following feature:
4 2 Henning Blohm
5
Upgrading a stateful Web application, i.e. a Web application that stores user data in its HTTP session typically implies downtime, and if the session state is not serializable and persisted during the upgrade, it does additionally imply that user state gets lost and typically that users need to log on again.
6
7
Using the Gateway, running sessions may be preserved and worker resources may still be assigned on the current software revision for as long as there are running sessions during a node upgrade and until all sessions have been terminated. The typical application of this feature is to roll out functional and user interface corrections without interrupting users. Users can switch over to post-upgrade software by terminating their session (e.g. via a log out) and starting a new one (e.g. by logging in again).
8
9 1 Henning Blohm
*Note:*
10 12 Henning Blohm
11 2 Henning Blohm
* This feature is relatively new and before you use it in production, you should have carefully tested your scenario.
12
* There are natural limitations to this feature. Upgrades that change the structure or semantics of persisted data or other resources that are shared across nodes cannot be handled this way.
13
14 6 Henning Blohm
h2. A sample on how to use Gateway
15 2 Henning Blohm
16 11 Henning Blohm
A sample can be found in the "z2-samples.gateway":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-gateway repository. Install as follows:
17
18
{{include(Install_sample_prefix)}}
19
20 1 Henning Blohm
Check out the sample
21 11 Henning Blohm
22 13 Henning Blohm
<pre><code class="bash">
23 12 Henning Blohm
git clone -b v2.8 https://www.z2-environment.net/git/z2-samples.gateway
24 11 Henning Blohm
</code></pre>
25
26 1 Henning Blohm
{{include(Install_sample_postfix)}}
27 11 Henning Blohm
28
Check out the *environment* module (that typically holds all configuration regarding the "environment" of the application - such as database connection and Web server configuration). This module is holding a Gateway configuration as described below. After re-starting your Z2 installation, try the following:
29 2 Henning Blohm
30 12 Henning Blohm
1. Open a browser and navigate to http://localhost:8080/z_gateway . Use (by default) user "z*" with password "z".
31 3 Henning Blohm
32
You should see this:
33
34
!gateway1.png!
35
36
2. Open another browser window and navigate to http://localhost:8080/adm (same user). Choose the group "Workers" and update.
37
38 4 Henning Blohm
Check for the current worker process and their state. You should see something like this:
39 3 Henning Blohm
40
!admin1.png!
41 1 Henning Blohm
42
Both web applications application create a HTTP session. Now go back to the Gateway user interface and press "Detach environment/webWorker@0 and sync". On your console you will see that another worker process started (called environment/webWorker@1) and if you update the worker list in the admin interface you should see something like this:
43 4 Henning Blohm
44
!admin2.png!
45
46 12 Henning Blohm
That is: One worker was _detached_ while another one is in state _started_<notextile></notextile>.
47 4 Henning Blohm
48 12 Henning Blohm
If you now refresh the Gateway user interface you will see that it is still served from *environment/webWorker@0*<notextile></notextile>. Press "log off". You should find that it now switched to *environment/webWorker@1*<notextile></notextile>.
49 4 Henning Blohm
50
Let's recap: Now we have a session on *environment/webWorker@0* via the admin user interface and one one *environment/webWorker@1* via the Gateway user interface.
51
52
3. Detach *environment/webWorker@1* by clicking "Detach environment/webWorker@1 and sync" on the Gateway user interface.
53
54 12 Henning Blohm
When checking the worker list you will now see something like this:
55 4 Henning Blohm
56
!admin3.png!
57
58 12 Henning Blohm
Remember that it is the Gateway user interface that keeps *environment/webWorker@1* alive. If you click on "log off" the session will be terminated, worker *environment/webWorker@1* served its purpose and will terminate, and the Gateway user interface will be served from *environment/webWorker@2*<notextile></notextile>. Checking the worker list you should see something like this:
59 5 Henning Blohm
60
!admin4.png!
61 1 Henning Blohm
62
Finally, if you wait 30 minutes until the session of the admin user interface has expired, also *environment/webWorker@0* will terminate.
63
64 7 Henning Blohm
h2. Enabling Gateway
65
66
The sample configuration in "z2-samples.gateway":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-gateway has a pre-configured Gateway setup. Here is how this differs from a regular non-Gateway setup:
67
68
h3. The Gateway Web server
69
70 12 Henning Blohm
As explained in the next section, when using Gateway, Z2 runs a Web server on the Home process in addition to Web servers in Web workers. All requests that go normally directly to the Web worker process will instead be handled on the Home process and forwarded appropriately to a Web worker process.
71 7 Henning Blohm
72
In order to enable this Web server, uncomment the system state participation in "environment/gateway/z.properties":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-gateway/revisions/master/entry/environment/gateway/z.properties as done in the sample.
73
74 12 Henning Blohm
The Gateway Web server is configured in "environment/gateway/jetty.xml":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-gateway/revisions/master/entry/environment/gateway/jetty.xml<notextile></notextile>. This is a regular Jetty configuration. Instead of being an ordinary Java Web container all requests are handled by a special Gateway Jetty handler.
75 7 Henning Blohm
76 12 Henning Blohm
The only part of this configuration that could be of interest to be changed is the normal connector settings (ports and concurrency) - just as you normally would tune your Jetty Web server - and the name of the worker process that is to receive the forwarded requests - the _Web worker process_<notextile></notextile>. The latter is defined in this section:
77 7 Henning Blohm
78 12 Henning Blohm
<pre><code>
79 14 Henning Blohm
<Set name="handler">
80
  <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
81
    <Set name="handlers">
82
      <Array type="org.eclipse.jetty.server.Handler">
83
        <Item>
84
          <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
85
        </Item>
86
        <Item> 
87
          <Call class="com.zfabrik.gateway.GatewayFactory" name="getHandler">
88
            <Set name="workerProcessComponentName">environment/webWorker</Set>
89
          </Call>
90
        </Item>
91
      </Array>
92
    </Set>
93
  </New>
94
</Set>
95 1 Henning Blohm
</code></pre>
96
97 8 Henning Blohm
Unless you want to change the name of the target worker process, you do not need to touch Gateway's jetty.xml.
98
99 10 Henning Blohm
h3. The Web worker Jetty configuration
100 1 Henning Blohm
101 10 Henning Blohm
When enabling Gateway, we want Web workers to not listen on the same port (default 8080) as Gateway. With Gateway configured, we want Web workers to only process Gateway requests - which are slightly different than normal HTTP requests due to some extra metadata passed on the proxy Web server running in the Home process.
102
103
In order to facilitate that, the Jetty configuration for the instance running on the Web worker is modified to use the "GatewayServer":https://redmine.z2-environment.net/projects/z2-base/repository/base/revisions/master/entry/com.zfabrik.gateway/java/src.api/com/zfabrik/gateway/worker/GatewayServer.java rather than the normal Jetty Server implementation class. This *GatewayServer* class computes the internal localhost port for proxy to web worker communication and communicates additional metadata on session usage to the proxy server of the Home process.
104
105
In terms of configuration we change the web server component descriptor to include "gateway.xml":https://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-gateway/revisions/master/entry/environment/webServer/gateway.xml and "gateway-http.xml":https://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-gateway/revisions/master/entry/environment/webServer/gateway-http.xml rather than *jetty.xml* and *jetty-http.xml*
106
107 12 Henning Blohm
The main difference is a) the use of
108 1 Henning Blohm
109 12 Henning Blohm
<pre><code>
110 15 Henning Blohm
<Configure id="Server" class="com.zfabrik.gateway.worker.GatewayServer">
111 10 Henning Blohm
...
112 15 Henning Blohm
</Configure>
113 10 Henning Blohm
</code></pre>
114
115
(gateway.xml) and b) the use of a Gateway connection factory (gateway-http.xml):
116
117 12 Henning Blohm
<pre><code>
118 14 Henning Blohm
 <Call name="addConnector">
119
    <Arg>
120
      <New id="httpConnector" class="org.eclipse.jetty.server.ServerConnector">
121 10 Henning Blohm
122 1 Henning Blohm
//...
123
124 14 Henning Blohm
        <Arg name="factories">
125
          <Array type="org.eclipse.jetty.server.ConnectionFactory">
126
            <Item>
127 10 Henning Blohm
128 14 Henning Blohm
              <!--  Use Gateway connection factory! -->
129
              <New class="com.zfabrik.gateway.worker.GatewayConnectionFactory">
130
                <Arg name="config"><Ref refid="httpConfig" /></Arg>
131
              </New>
132 12 Henning Blohm
133 14 Henning Blohm
            </Item>
134
          </Array>
135
        </Arg>
136 12 Henning Blohm
137 10 Henning Blohm
//...
138
139 14 Henning Blohm
    <!-- gateway specific settings on worker node -->
140
        <Set name="host">localhost</Set>
141
        <!-- Use Gateway port setting!s -->
142
        <Set name="port"><SystemProperty name="com.zfabrik.gateway.jetty.http.host"/></Set>
143 10 Henning Blohm
144 14 Henning Blohm
      </New>
145
    </Arg>
146
  </Call>
147 10 Henning Blohm
</code></pre>
148
149
The purpose of the "GatewayConnectionFactory":https://redmine.z2-environment.net/projects/z2-base/repository/base/revisions/master/entry/com.zfabrik.gateway/java/src.api/com/zfabrik/gateway/worker/GatewayConnectionFactory.java is to use Gateway specific connection implementations "GatewayConnection":https://redmine.z2-environment.net/projects/z2-base/repository/base/revisions/master/entry/com.zfabrik.gateway/java/src.api/com/zfabrik/gateway/worker/GatewayConnection.java that allow us to add the additional metadata provided from the GatewayServer class (above).
150 2 Henning Blohm
151 6 Henning Blohm
h3. Running the Gateway user interface
152 1 Henning Blohm
153 12 Henning Blohm
Finally, in order to actually trigger "Detach & Sync", you should enable the Gateway user interface by adding a dependency to *com.zfabrik.gateway/web* to "environment/webWorkerUp":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-gateway/revisions/master/entry/environment/webWorkerUp.properties<notextile></notextile>.
154 1 Henning Blohm
155 9 Henning Blohm
h2. How does Gateway work
156 1 Henning Blohm
157 9 Henning Blohm
Gateway consists of two parts:
158 1 Henning Blohm
159 6 Henning Blohm
h3. The reverse proxy Gateway handler
160
161
When using Gateway, there is a Jetty Web server running on the Home process. This Web server maintains a mapping of sessions to Web worker nodes. Any newly created session will be assigned to the latest running Web worker process. All request will be routed to the Web worker process assigned to their session or, if there is no session id on the request, to the latest Web worker process.
162
163 1 Henning Blohm
On every Web worker process there is another Web server that accepts requests forwarded from the Home process and subsequently treats them as if they were ordinary HTTP requests in the first place.
164
165 6 Henning Blohm
h3. Detached worker processes
166
167 12 Henning Blohm
Apart from being stopped, starting, started, or stopping, Z2 worker processes can also be in _detached_ state. When a worker process is detached, it will terminate itself unless there is still unfinished work. Open Web application sessions is one type of such unfinished work.
168 9 Henning Blohm
169 12 Henning Blohm
In other words, if a worker has no open sessions and is being detached, it will terminate itself right away.
170 6 Henning Blohm
171
Finally, when the Home process runs a synchronization, detached worker processes do not count as running processes. That is, when the synchronization finds that there is only detached worker process instances of a worker process component, it will start another one.
172
173
That is why the Gateway user interface will not only detach a worker process but also trigger a synchronization. Here is a diagram illustrating the flow from detach and sync to worker process termination:
174
175
!steady_workers1.png!
176
177
h2. Ports of worker processes
178
179 12 Henning Blohm
Worker processes open ports to receive Web requests but also for JVM debugging and JMX access. These ports are configured in the worker process component definition. See for example "environment/webWorker":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-gateway/revisions/master/entry/environment/webWorker.properties<notextile></notextile>. These ports are actually base port numbers and the real port to be used is computed from a _generation_ number that is also part of the worker process instance name that you saw above. I.e. the instance name *environment/webWorker@2* is generation 2 of the worker process component *environment/webWorker*<notextile></notextile>.
180 6 Henning Blohm
181 1 Henning Blohm
The port configurations in worker process components are:
182
183
|_. Property |_. Description |_. Typical value |
184 12 Henning Blohm
| worker.debug.port | Base port of the JVM debug port to use. If the home process has remote debugging enabled, worker processes will also be configured for remote debugging. | 5100 in environment/webWorker |
185
| worker.jmx.port | Base port of the remote JMX access. Will be ignored if no JMX access configured | 7800 for environment/webWorker |
186
| com.zfabrik.gateway.port | Base port of the web worker side of Gateway. Will only listen to localhost and only be used, if Gateway is configured | 8800 in environment/webWorker |