Du bist nicht angemeldet.

JuKu

Profi

  • »JuKu« ist der Autor dieses Themas

Beiträge: 574

Registrierungsdatum: 29.09.2011

Danksagungen: 48

  • Private Nachricht senden

1

25.12.2014, 16:54

Backend Anwendungen für Server skalierbar programmieren

KBackend Anwendungen für Server skalierbar programmieren

Um eine Anwendung redundant und skalierbar zu entwickeln, müssen mehrere Server zusammenarbeiten und die Last muss über die vielen Server verteilt werden.
Mehrere Server bilden dazu meist einen Verbund von Servern, ein sog. Cluster, welches sich meist nach außen hin auch wie ein einzelnes System verhält und z.B. auch nur 1 öffentliche IP hat.
Ein Beispiel ist der Google DNS Server mit der IP 4.4.4.4 bzw. 8.8.8.8, welcher mehrere Mio. Anfragen erhält, aber auch nur 1 oder wenige IPs besitzt.
Mehrere 10.000 Server arbeiten dann die Anfragen ab.
Die 1. Anfrage kann z.B. der 1. DNS Server erhalten, die 2. Anfrage der 2. DNS Server usw.



Dazu nutzt man meist einen Load Balancer.
Dazu kann z.B. bei Webanwendungen ein nginx Webserver als Proxy und Load Balancer konfiguriert werden, welcher nach außen hin auch nur 1 öffentliche IP besitzen kann.
Wenn man die Website dann aufruft, erhält der Load Balancer, also der nginx Webserver die Anfrage und verteilt diese an die n Webserver.
Der Load Balancer sorgt somit dafür, dass ein Dienst ständig erreichbar ist.
Bei Webservern ist diese Lastverteilung z.B. enorm wichtig, da ein einzelner Host nur eine begrenzte Menge an Anfragen auf einmal beantworten kann.
https://www.thomas-krenn.com/de/tkmag/ex…leicht-gemacht/

Bei statischen Inhalten müssen die Server lediglich die Daten zurückgeben, aber bei dynamischen Inhalten müssen alle Server zusammen arbeiten.
Das Grund Problem dabei ist, dass Server A dabei auf die Daten von Server B zugreifen können muss.
Die Daten liegen dazu meist in Datenbank Systemen oder die Server tauschen die Daten einzeln aus.
Diese Webserver greifen dann meist auf die selbe Datenbank drauf zu oder auf mehrere MySql Datenbanken, die gespiegelt sind.

[img]http://www.developertalk.de/index.php?page=Attachment&attachmentID=241&h=0eba374b3722ad3b36ec2bb1713f737993c0ec87[/img]
Skalierbare Anwendungen.png

Diese Variante ist aber nicht die beste und eignet sich auch nur bis zu einer bestimmten Anzahl von Anfragen, da die MySql Datenbank sonst nicht schnell genug Werte ändern kann, weil die Last zu hoch ist oder der Proxy Server, der auch als Tunnel fungiert, nur eine bestimmte Anzahl von Anfragen annehmen kann.
Ein einfacher Load Balancer würde, wie in diesem Fall, den Webserver z.B. wie folgt bestimmen:
n = Anzahl der Anfragen MOD Anzahl der Server
Dabei würde der Load Balancer nicht die eig. Last des Servers berücksichtigen, sondern lediglich die Anfragen auf genau n Webserver verteilen.

Oftmals wird aber auch eine NoSql Datenbank zur Speicherung von Daten benötigt.
Damit können ganze HashMaps, Lists usw. gespeichert werden.

Hazelcast

Eine solche NoSQL Datenbank ist z.B. Hazelcast.
Hazelcast ist ein Open Source In-Memory Data Grid, welches aber auch eine Enterprise Edition bietet und hält alle Daten im RAM.
Mit Hazelcast können ganze Cluster gebildet werden, welche die Daten redundant zur Verfügung stellen und Backups unter den Servern verteilen, sodass bei einem Ausfall einer Hazelcast Instanz eine andere Hazelcast Instanz die Daten bereit stellt.
Die Load Balancer in Hazelcast verteilen dabei die Daten so, dass alle Server die Daten schnell genug zurückgeben können.
Ein solches Cluster kann aus 1 Server, 1000 Servern oder n Servern bestehen.

Die eig. Server Application muss somit nur noch einen Client zu einer Hazelcast Instanz öffnen und die Daten auslesen oder speichern.

Beispiel: Ein Chat Server
Als Beispiel wollen wir einen kleinen Chat Server programmieren, welcher mehrere 10.000 Anfragen standhalten können soll.
Der Chat Server soll n User und n Räume haben, in jedem Raum können die User etwas schreiben.
Diese Daten sollen alle in Hazelcast gespeichert werden und es soll mehrere Server Applications geben, die zusammen arbeiten.

Dieses Tutorial wird noch ergänzt.
Wenn euch mein Beitrag weitergeholfen hat, drückt auf "Bedanken"!
Danke! :D

Dieser Beitrag wurde bereits 33 mal editiert, zuletzt von »JuKu« (31.12.2014, 18:31)


Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

Patrick (04.01.2015)

Erik

Profi

Beiträge: 1 274

Registrierungsdatum: 22.06.2011

Wohnort: Deutschland ;)

Danksagungen: 307

  • Private Nachricht senden

2

26.12.2014, 01:09

Bin gespannt, hört sich interessant an :)
Beste Webite im Internet ( ͡° ͜ʖ ͡°)
xinra.de

JuKu

Profi

  • »JuKu« ist der Autor dieses Themas

Beiträge: 574

Registrierungsdatum: 29.09.2011

Danksagungen: 48

  • Private Nachricht senden

3

28.12.2014, 14:02

Vielen Dank! :)
Wieso funktioniert der img Tag derzeit nicht? :)
Wenn euch mein Beitrag weitergeholfen hat, drückt auf "Bedanken"!
Danke! :D

JuKu

Profi

  • »JuKu« ist der Autor dieses Themas

Beiträge: 574

Registrierungsdatum: 29.09.2011

Danksagungen: 48

  • Private Nachricht senden

4

31.12.2014, 18:27

Einrichtung des ChatSystem Projects

Unsere ChatServer Infrastructure soll wie folgt aussehen:


Es gibt 2 Load Balancer, wobei beide die gleichen Daten halten, der eine also lediglich ein Backup bereitstellt.
Alle Server sind mit dem Load Balancer verbunden und schicken regelmäßig ihre Load Werte, wie viele Clients derzeit auf den Servern sind und wie hoch die Auslastung der Server ist usw.
Jeder Server hat in diesem Beispiel eine eigene öffentliche IP, damit wir keinen Proxy Server benötigen.

Wer kein Maven nutzt, muss 4 einzelne Projekte erstellen, wer Maven nutzt kann ein neues Projekt erstellen und 4 Module hinzufügen:

Quellcode

1
2
3
4
5
6
<modules>
        <module>ChatSystem Library</module>
        <module>LoadBalancer</module>
        <module>ChatClient</module>
        <module>ChatServer</module>
    </modules>


Die pom.xml aus dem Hauptprojekt sieht wie folgt aus:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jukusoft.chatsystem</groupId>
    <artifactId>com.jukusoft.chatsystem</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>ChatSystem Library</module>
        <module>LoadBalancer</module>
        <module>ChatClient</module>
        <module>ChatServer</module>
    </modules>


</project>


ChatSystem Library pom.xml:

Spoiler Spoiler


Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>com.jukusoft.chatsystem</artifactId>
        <groupId>com.jukusoft.chatsystem</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>com.jukusoft.chatsystem.lib</artifactId>


</project>



ChatSystem LoadBalancer pom.xml:

Spoiler Spoiler


Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>com.jukusoft.chatsystem</artifactId>
        <groupId>com.jukusoft.chatsystem</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>com.jukusoft.chatsystem.loadbalancer</artifactId>


</project>



Das Package com.jukusoft.chatsystem.lib soll alle Interface und Klassen enthalten, die mehrere Module nutzen, wie der ChatClient und der ChatServer.
Fügen wir nun eine Main Klasse zum Module LoadBalancer hinzu:

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
package com.jukusoft.chatsystem.loadbalancer;

/**
 * Created by Justin on 31.12.2014.
 */
public class LoadBalancerMain {

    public static void main (String[] args) {
        //
    }

}


Diese Klasse ist die Main Klasse und die main Methode wird beim Start des Packages ausgeführt.
Unser Load Balancer soll nicht nur die Last, also die Clients auf die verschiedenen Server verteilen, sondern auch als Login Server dienen.



Als nächstes fügen wir eine Konfigurationsdatei hinzu.

loadbalancer.cfg:

Quellcode

1
2
3
4
5
6
7
[LoadBalancer]
loadBalancer=127.0.0.1:50234
loadBalancer=127.0.0.1:50235

[Hazelcast]
ip=127.0.0.1
port=55345


Die Konfigurationsdatei loadbalancer.cfg enthält die Konfiguration des Load Balancers und eine Liste aller anderen Load Balancer, wie z.B. den Backup Load Balancer.
Um diese Konfigurationsdatei einfach auszulesen nutzen wir die Library Ini4J.

Wer Maven nutzt muss lediglich die pom.xml im Module LoadBalancer wie folgt anpassen:

Spoiler Spoiler

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>com.jukusoft.chatsystem</artifactId>
        <groupId>com.jukusoft.chatsystem</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>com.jukusoft.chatsystem.loadbalancer</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.ini4j</groupId>
            <artifactId>ini4j</artifactId>
            <version>0.5.2</version>
        </dependency>

    </dependencies>


</project>
Wenn euch mein Beitrag weitergeholfen hat, drückt auf "Bedanken"!
Danke! :D

Dieser Beitrag wurde bereits 17 mal editiert, zuletzt von »JuKu« (31.12.2014, 20:37)


Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

Patrick (04.01.2015)

JuKu

Profi

  • »JuKu« ist der Autor dieses Themas

Beiträge: 574

Registrierungsdatum: 29.09.2011

Danksagungen: 48

  • Private Nachricht senden

5

01.01.2015, 16:19

Um diese Konfigurationsdatei auszulesen, erstellen wir eine neue Klasse LoadBalancerConfig.

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.jukusoft.chatsystem.loadbalancer.config;

import org.ini4j.Ini;
import org.ini4j.Profile;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Justin on 31.12.2014.
 */
public class LoadBalancerConfig {

    protected Ini ini = null;

    public void loadConfig (String filename) {
        File file = new File(filename);

        if (!file.exists()) {
            this.createDefaultConfigFile(filename);
        }

        this.ini = new Ini();
        try {
            ini.load(new FileReader(file));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Ini.Section getSection (String section) {
        return this.ini.get(section);
    }

    public List<String> listLoadBalancers () {
        ArrayList<String> list = new ArrayList<String>();

        for (String loadBalancer : this.getSection("LoadBalancer").getAll("loadBalancer")) {
            list.add(loadBalancer);
        }

        return list;
    }

    public void createDefaultConfigFile (String filename) {
        File file = new File(filename);
    }

}


Diese Klasse nutzt die Ini4J library und lädt in der Methode loadConfig(String filename) die Konfigurationsdatei in ein Ini Object.
Da eine ini Datei meist aus mehreren Sections besteht, wie die Sections LoadBalancer und Hazelcast, erstellen wir auch noch die Methode getSection(String section), welche ein Ini.Section Object zurückgibt, welches wir dann auslesen können.
Die Methode listLoadBalancers() soll eine Liste mit allen LoadBalancern zurückgeben, da zu diesen eine Verbindung hergestellt werden muss.
Alle LoadBalancer müssen synchronisiert werden und die selben Daten besitzen.
Bei einem Ausfall eines Load Balancers soll der andere Load Balancer dessen Arbeit übernehmen.
Wenn euch mein Beitrag weitergeholfen hat, drückt auf "Bedanken"!
Danke! :D

JuKu

Profi

  • »JuKu« ist der Autor dieses Themas

Beiträge: 574

Registrierungsdatum: 29.09.2011

Danksagungen: 48

  • Private Nachricht senden

6

01.01.2015, 16:43

Als Networking Library wollen wir Netty.io verwenden.

Netty basiert auf NIO, der neuen I/O API von Java.
NIO unterstützt auch die Non-Blocking-IO, welche die normale IO Api von Java nicht unterstützt.
Non-Blocking-IO bedeutet, dass nicht mehr alles synchon sein muss, sondern auch eine asynchrone Übertragung möglich ist und die Application gleichzeitig lesen und schreiben kann, indem mehrere Threads genutzt werden.

Wer Maven nicht nutzt, muss die JAR von Netty.io herunterladen, wer Maven nutzt kann die folgenden Zeilen in der pom.xml im Module LoadBalancer hinzufügen:

Quellcode

1
2
3
4
5
<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty-all</artifactId>
	<version>5.0.0.Alpha1</version>
</dependency>


pom.xml:

Spoiler Spoiler


Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>com.jukusoft.chatsystem</artifactId>
        <groupId>com.jukusoft.chatsystem</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>com.jukusoft.chatsystem.loadbalancer</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.ini4j</groupId>
            <artifactId>ini4j</artifactId>
            <version>0.5.2</version>
        </dependency>

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>5.0.0.Alpha1</version>
        </dependency>

    </dependencies>


</project>

Wenn euch mein Beitrag weitergeholfen hat, drückt auf "Bedanken"!
Danke! :D

JuKu

Profi

  • »JuKu« ist der Autor dieses Themas

Beiträge: 574

Registrierungsdatum: 29.09.2011

Danksagungen: 48

  • Private Nachricht senden

7

01.01.2015, 16:49

Netty kann sowohl bytes als auch ganze Java OObjects übertragen, wenn man einen Encoder und Decoder dafür einbindet.

Als nächstes benötigen wir eine Klasse LoadBalancerConnection im Module LoadBalancer, welche eine Verbindung zu einem anderem LoadBalancer repräsentiert.
Wenn euch mein Beitrag weitergeholfen hat, drückt auf "Bedanken"!
Danke! :D

liro

Fortgeschrittener

Beiträge: 180

Danksagungen: 36

  • Private Nachricht senden

8

19.01.2015, 13:11


Der Chat Server soll n User und n Räume haben, in jedem Raum können die User etwas schreiben.


Wieso darf es nur genauso soviele Räume wie Benutzer geben? oder meintest du n User und m Räume?

Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

Erik (19.01.2015)

JuKu

Profi

  • »JuKu« ist der Autor dieses Themas

Beiträge: 574

Registrierungsdatum: 29.09.2011

Danksagungen: 48

  • Private Nachricht senden

9

19.01.2015, 17:35

Dann n User und x Räume. :D
Jeder User kann mehrere Räume erstellen. :D
Wenn euch mein Beitrag weitergeholfen hat, drückt auf "Bedanken"!
Danke! :D

Ähnliche Themen