blob: 05c968903721d19bf36770c20fad4ac7d1f1cd9a [file] [log] [blame]
<!DOCTYPE html>
<html class="no-js">
<head lang="en-us">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=10" />
<title>Clustering - Eclipse hawkBit</title>
<meta name="generator" content="Hugo 0.56.3" />
<meta name="description" content="IoT. Update. Device.">
<link rel="canonical" href="https://www.eclipse.org/hawkbit/guides/clustering/">
<meta name="author" content="The Eclipse hawkBit Project">
<meta property="og:url" content="https://www.eclipse.org/hawkbit/guides/clustering/">
<meta property="og:title" content="Eclipse hawkBit">
<meta property="og:image" content="https://www.eclipse.org/hawkbit/images/hawkbit_icon.png">
<meta name="apple-mobile-web-app-title" content="Eclipse hawkBit">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="shortcut icon" type="image/x-icon" href="https://www.eclipse.org/hawkbit/images/favicon.ico">
<link rel="icon" type="image/x-icon" href="https://www.eclipse.org/hawkbit/images/favicon.ico">
<style>
@font-face {
font-family: 'Icon';
src: url('https://www.eclipse.org/hawkbit/fonts/icon.eot');
src: url('https://www.eclipse.org/hawkbit/fonts/icon.eot')
format('embedded-opentype'),
url('https://www.eclipse.org/hawkbit/fonts/icon.woff')
format('woff'),
url('https://www.eclipse.org/hawkbit/fonts/icon.ttf')
format('truetype'),
url('https://www.eclipse.org/hawkbit/fonts/icon.svg')
format('svg');
font-weight: normal;
font-style: normal;
}
</style>
<link rel="stylesheet" href="https://www.eclipse.org/hawkbit/stylesheets/application.css">
<link rel="stylesheet" href="https://www.eclipse.org/hawkbit/stylesheets/temporary.css">
<link rel="stylesheet" href="https://www.eclipse.org/hawkbit/stylesheets/palettes.css">
<link rel="stylesheet" href="https://www.eclipse.org/hawkbit/stylesheets/highlight/highlight.css">
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Ubuntu:400,700|Ubuntu&#43;Mono">
<style>
body, input {
font-family: 'Ubuntu', Helvetica, Arial, sans-serif;
}
pre, code {
font-family: 'Ubuntu Mono', 'Courier New', 'Courier', monospace;
}
</style>
<link rel="stylesheet" href="https://www.eclipse.org/hawkbit/css/hawkbit.css">
<link rel="stylesheet" href="//www.eclipse.org/eclipse.org-common/themes/solstice/public/stylesheets/vendor/cookieconsent/cookieconsent.min.css">
<script src="https://www.eclipse.org/hawkbit/javascripts/modernizr.js"></script>
<script src="//www.eclipse.org/eclipse.org-common/themes/solstice/public/javascript/vendor/cookieconsent/default.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
</head>
<body class="palette-primary-deep-purple palette-accent-light-green">
<div class="backdrop">
<div class="backdrop-paper"></div>
</div>
<input class="toggle" type="checkbox" id="toggle-drawer">
<input class="toggle" type="checkbox" id="toggle-search">
<label class="toggle-button overlay" for="toggle-drawer"></label>
<header class="header">
<nav aria-label="Header">
<div class="bar default">
<div class="button button-menu" role="button" aria-label="Menu">
<label class="toggle-button icon icon-menu" for="toggle-drawer">
<span></span>
</label>
</div>
<div class="stretch">
<div class="title">
Clustering
</div>
</div>
<div class="button button-github" role="button" aria-label="GitHub">
<a href="https://github.com/eclipse/hawkbit" title="@eclipse/hawkbit on GitHub" target="_blank" class="toggle-button icon icon-github"></a>
</div>
<div class="button button-github" role="button" aria-label="Gitter">
<a href="https://gitter.im/eclipse/hawkbit" title="@eclipse/hawkbit on Gitter" target="_blank" class="toggle-button icon fab fa-gitter"></a>
</div>
<div class="button button-github" role="button" aria-label="Docker">
<a href="https://hub.docker.com/u/hawkbit" title="hawkbit on Docker Hub" target="_blank" class="toggle-button icon fab fa-docker"></a>
</div>
</div>
<div class="bar search">
<div class="button button-close" role="button" aria-label="Close">
<label class="toggle-button icon icon-back" for="toggle-search"></label>
</div>
<div class="stretch">
<div class="field">
<input class="query" type="text" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck>
</div>
</div>
<div class="button button-reset" role="button" aria-label="Search">
<button class="toggle-button icon icon-close" id="reset-search"></button>
</div>
</div>
</nav>
</header>
<main class="main">
<div class="drawer">
<nav aria-label="Navigation">
<a href="https://www.eclipse.org/hawkbit/" class="project">
<div class="banner">
<div class="logo">
<img src="https://www.eclipse.org/hawkbit/images/hawkbit_icon.png">
</div>
<div class="name">
<strong>Eclipse hawkBit&trade; </strong>
<br>
eclipse/hawkbit
</div>
</div>
</a>
<div class="scrollable">
<div class="wrapper">
<ul class="repo">
<li class="repo-download">
<a href="https://hawkbit.eclipse.org" target="_blank" title="hawkBit Sandbox" data-action="sandbox">
<i class="fas fa-desktop"></i> &nbsp; Sandbox
</a>
</li>
<li class="repo-stars">
<a href="https://github.com/eclipse/hawkbit/stargazers" target="_blank" title="Stargazers" data-action="star">
<i class="icon icon-star"></i> Stars
<span class="count">&ndash;</span>
</a>
</li>
</ul>
<hr>
<div class="toc">
<ul>
<li>
<a title="What is hawkBit" href="/hawkbit/whatishawkbit/">
What is hawkBit
</a>
</li>
<li>
<a title="Getting started" href="/hawkbit/gettingstarted/">
Getting started
</a>
</li>
<li>
<a title="Guides" href="/hawkbit/guides/">
Guides
</a>
</li>
<li>
<a title="Features" href="/hawkbit/features/">
Features
</a>
</li>
<li>
<a title="Concepts" href="/hawkbit/concepts/">
Concepts
</a>
</li>
<li>
<a title="Architecture" href="/hawkbit/architecture/">
Architecture
</a>
</li>
<li>
<a title="Management UI" href="/hawkbit/ui/">
Management UI
</a>
</li>
<li>
<a title="APIs" href="/hawkbit/apis/">
APIs
</a>
</li>
<li>
<a title="Community" href="/hawkbit/community/">
Community
</a>
</li>
<li>
<a title="Release notes" href="/hawkbit/release-notes/">
Release notes
</a>
</li>
</ul>
<hr>
<ul>
<li>
<a href="https://gitter.im/eclipse/hawkbit?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" title="Chat on Gitter" target="_blank">
<img src="https://badges.gitter.im/eclipse/hawkbit.svg" />
</a>
</li>
<li>
<a href="https://circleci.com/gh/eclipse/hawkbit" title="Circle CI Status" target="_blank">
<img src="https://circleci.com/gh/eclipse/hawkbit.svg?style=shield" />
</a>
</li>
<li>
<a href="https://sonar.ops.bosch-iot-rollouts.com" title="SonarQube Status" target="_blank">
<img src="https://sonar.ops.bosch-iot-rollouts.com/api/badges/gate?key=org.eclipse.hawkbit:hawkbit-parent" />
</a>
</li>
<li>
<a href="https://maven-badges.herokuapp.com/maven-central/org.eclipse.hawkbit/hawkbit-parent" title="Maven Central Status" target="_blank">
<img src="https://maven-badges.herokuapp.com/maven-central/org.eclipse.hawkbit/hawkbit-parent/badge.svg" />
</a>
</li>
</ul>
</div>
</div>
</div>
</nav>
</div>
<article class="article">
<div class="wrapper">
<h1>Clustering </h1>
<p>hawkBit is able to run in a cluster with some constraints. This guide provides insights in the basic concepts and how to setup your own cluster. You can find additional information in the <a href="https://github.com/eclipse/hawkbit/blob/master/hawkbit-runtime/hawkbit-update-server/README.md">hawkBit runtimes&rsquo;s README</a>.</p>
<h2 id="big-picture">Big picture</h2>
<p><img src="../../images/overall_cluster.png" alt="" /></p>
<h2 id="events">Events</h2>
<p>Event communication between nodes is based on <a href="https://cloud.spring.io/spring-cloud-bus/">Spring Cloud Bus</a> and <a href="http://docs.spring.io/spring-cloud-stream/docs/current/reference/htmlsingle/">Spring Cloud Stream</a>. There are different <a href="http://docs.spring.io/spring-cloud-stream/docs/current/reference/htmlsingle/#_binders">binder implementations</a> available. The <em>hawkbit Update Server</em> uses RabbitMQ binder. Every node gets his own queue to receive cluster events, the default payload is JSON.
If an event is thrown locally at one node, it will be automatically delivered to all other available nodes via the Spring Cloud Bus&rsquo;s topic exchange:</p>
<p><img src="../../images/eventing-within-cluster.png" alt="" /></p>
<p>Via the ServiceMatcher you can check whether an event happened locally at one node or on a different node.
<code>serviceMatcher.isFromSelf(event)</code></p>
<h2 id="caching">Caching</h2>
<p>Every node is maintaining its own caches independent from other nodes. So there is no globally shared/synchronized cache instance within the cluster. In order to keep nodes in sync a TTL (time to live) can be set for all caches to ensure that after some time the cache is refreshed from the database. To enable the TTL just set the property &ldquo;hawkbit.cache.global.ttl&rdquo; (value in milliseconds). Of course you can implement a shared cache, e.g. Redis.
See <a href="https://github.com/eclipse/hawkbit/blob/master/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/cache/CacheAutoConfiguration.java">CacheAutoConfiguration</a></p>
<h2 id="schedulers">Schedulers</h2>
<p>Every node has multiple schedulers which run after a defined period of time. All schedulers always run on every node. This has to be kept in mind e.g. if the scheduler executes critical code which has to be executed only once.</p>
<h2 id="known-constraints">Known constraints</h2>
<h3 id="ui-sessions">UI sessions</h3>
<p>As of today hawkBit is not storing user sessions in a shared, cluster wide cache. Session is only bound to the node where the login took place. If this node is going down for whatever reason, the session is lost and the user is forced to login again.
In case that&rsquo;s not an option, you can help yourself by introducing a shared session cache based on e.g. Redis.
Furthermore hawkBit is not supporting session stickiness out of the box either. However most of the well known load balancer out there can solve this issue.</p>
<h3 id="caching-of-download-ids">Caching of download IDs</h3>
<p>The downloadId is generated and stored in the DownloadIdCache. It is used for downloading an artifact.
In hawkBit exists an interface called &ldquo;<a href="https://github.com/eclipse/hawkbit/blob/master/hawkbit-core/src/main/java/org/eclipse/hawkbit/cache/DownloadIdCache.java">DownloadIdCache</a>&rdquo; and one implementation of it: &ldquo;DefaultDownloadIdCache&rdquo;. This default implementation can&rsquo;t be used within a cluster. Its containing data is only available inside one node and can&rsquo;t be shared with other nodes. E.g. the downloadId which is stored in this cache after authentication on node A can only be used for downloading the artifact by node A.
In a cluster-capable environment this fact can lead to issues as it could happen, that the downloadId is stored on node A and node B would like to download the artifact by means of the downloadId which is not available on node B. To solve this issue you can use a cluster-shared cache e.g. Redis or create a new cluster-aware implementation of the interface &ldquo;DownloadIdCache&rdquo;.</p>
<h3 id="denial-of-service-dos-filter">Denial-of-Service (DoS) filter</h3>
<p>hawkBit owns the feature of guarding itself from DoS attacks, a <a href="https://github.com/eclipse/hawkbit/blob/master/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/DosFilter.java">DoS filter</a>. It reduces the maximum number of requests per seconds which can be configured for read and write requests.
This mechanism is only working for every node separately, i.e. in a cluster environment the worst-case behaviour would be that the maximum number of requests per seconds will be increased to its product if every request is handled by a different node.
The same constraint exists with the validator to check if a user tried too many logins within a defined period of time.</p>
<aside class="copyright" role="note">
<div class="logo">
<a href="https://www.eclipse.org" target="_blank">
<img src="/hawkbit/images/eclipse_foundation_logo.png" />
</a>
</div>
<p class="notice">
&copy; 2020 The Eclipse hawkBit Project &ndash;
Documentation built with
<a href="https://www.gohugo.io" target="_blank">Hugo</a>
using the
<a href="http://github.com/digitalcraftsman/hugo-material-docs" target="_blank">Material</a> theme.
</p>
<p class="quickLinks">
<a href="http://www.eclipse.org/legal/privacy.php" target="_blank">
&gt; Privacy Policy
</a>
<a href="http://www.eclipse.org/legal/termsofuse.php" target="_blank">
&gt; Terms of Use
</a>
<a href="http://www.eclipse.org/legal/copyright.php" target="_blank">
&gt; Copyright Agent
</a>
<a href="http://www.eclipse.org/legal" target="_blank">
&gt; Legal
</a>
<a href="https://www.eclipse.org/org/documents/epl-v10.php" target="_blank">
&gt; License
</a>
</p>
</aside>
<footer class="footer">
<nav class="pagination" aria-label="Footer">
<div class="previous">
<a href="https://www.eclipse.org/hawkbit/guides/customtheme/" title="Custom Theme">
<span class="direction">
Previous
</span>
<div class="page">
<div class="button button-previous" role="button" aria-label="Previous">
<i class="icon icon-back"></i>
</div>
<div class="stretch">
<div class="title">
Custom Theme
</div>
</div>
</div>
</a>
</div>
<div class="next">
<a href="https://www.eclipse.org/hawkbit/guides/feignclient/" title="Feign Client">
<span class="direction">
Next
</span>
<div class="page">
<div class="stretch">
<div class="title">
Feign Client
</div>
</div>
<div class="button button-next" role="button" aria-label="Next">
<i class="icon icon-forward"></i>
</div>
</div>
</a>
</div>
</nav>
</footer>
</div>
</article>
<div class="results" role="status" aria-live="polite">
<div class="scrollable">
<div class="wrapper">
<div class="meta"></div>
<div class="list"></div>
</div>
</div>
</div>
</main>
<script>
var base_url = 'https:\/\/www.eclipse.org\/hawkbit\/';
var repo_id = 'eclipse\/hawkbit';
</script>
<script src="https://www.eclipse.org/hawkbit/javascripts/application.js"></script>
<script>
/* Add headers to scrollspy */
var headers = document.getElementsByTagName("h2");
var scrollspy = document.getElementById('scrollspy');
if(scrollspy) {
if(headers.length > 0) {
for(var i = 0; i < headers.length; i++) {
var li = document.createElement("li");
li.setAttribute("class", "anchor");
var a = document.createElement("a");
if(!headers[i].id)
a.setAttribute("href", headers[i].parentNode.href);
else
a.setAttribute("href", "#" + headers[i].id);
a.setAttribute("title", headers[i].innerHTML);
a.innerHTML = headers[i].innerHTML;
li.appendChild(a);
scrollspy.appendChild(li);
}
} else {
scrollspy.parentElement.removeChild(scrollspy)
}
/* Add permanent link next to the headers */
var headers = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
for(var i = 0; i < headers.length; i++) {
var a = document.createElement("a");
a.setAttribute("class", "headerlink");
a.setAttribute("href", "#" + headers[i].id);
a.setAttribute("title", "Permanent link");
a.innerHTML = "#";
headers[i].appendChild(a);
}
}
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</body>
</html>