Skip to content

Commit

Permalink
Merge pull request #83 from kuzzleio/3.2.11-proposal
Browse files Browse the repository at this point in the history
Bug fixes

    [ #78 ] Do not delete existing strategies at start (benoitvidis)
    [ #76 ] Strategies in redis (benoitvidis)

Enhancements

    [ #82 ] Make this plugin compatible with Node.js 10+ (scottinet)
    [ #80 ] Coverage (benoitvidis)
    [ #79 ] Readme update (benoitvidis)

Others

    [ #77 ] 1st try for functional tests on travis (benoitvidis)
  • Loading branch information
Aschen authored Jun 14, 2019
2 parents f3e0ad1 + e49b1e2 commit 59430f5
Show file tree
Hide file tree
Showing 25 changed files with 3,333 additions and 2,342 deletions.
94 changes: 77 additions & 17 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,30 +1,90 @@
dist: trusty
dist: xenial
sudo: required
group: edge
node_js: "8"
jdk: oraclejdk8
jdk: openjdk8

services:
- docker
- docker

install:
- sudo apt update
- sudo apt install -y build-essential python-dev libzmq3-dev
- sudo apt update
- sudo apt install -y build-essential python-dev libzmq3-dev

script:
- npm install --unsafe-perm
- npm test
- npm run codecov
- bash test/travis-bin/sonar.sh
jobs:
include:

# -------------------------------------------------------------------------
# Unit tests
# -------------------------------------------------------------------------
- name: Unit tests
if: type = pull_request OR type = cron OR type = push AND branch =~ ^master|.*-dev
script:
- npm install --unsafe-perm
- npm run lint
- npm run unit-test
- npm run codecov
- bash test/travis-bin/sonar.sh

# -------------------------------------------------------------------------
# Functional tests - Redis 3.2
# -------------------------------------------------------------------------
- name: Functional tests - Redis 3.2
if: type = cron OR type = push AND branch = master
env:
- DOCKER_COMPOSE_VERSION=1.24.0
- REDIS_VERSION=3.2
before_install:
- sudo rm /usr/local/bin/docker-compose
- sudo curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
- sudo chmod +x /usr/local/bin/docker-compose
- sudo sysctl -w vm.max_map_count=262144
- sudo sysctl -w fs.inotify.max_user_watches=524288
script:
- npm run functional-test

# -------------------------------------------------------------------------
# Functional tests - Redis 4
# -------------------------------------------------------------------------
- name: Functional tests- Redis 4
if: type = cron OR type = push AND branch = master
env:
- DOCKER_COMPOSE_VERSION=1.24.0
- REDIS_VERSION=4
before_install:
- sudo rm /usr/local/bin/docker-compose
- sudo curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
- sudo chmod +x /usr/local/bin/docker-compose
- sudo sysctl -w vm.max_map_count=262144
- sudo sysctl -w fs.inotify.max_user_watches=524288
script:
- npm run functional-test

# -------------------------------------------------------------------------
# Functional tests - Redis 5
# -------------------------------------------------------------------------
- name: Functional tests - Redis 5
if: type = cron OR type = push AND branch = master
env:
- DOCKER_COMPOSE_VERSION=1.24.0
- REDIS_VERSION=5
before_install:
- sudo rm /usr/local/bin/docker-compose
- sudo curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
- sudo chmod +x /usr/local/bin/docker-compose
- sudo sysctl -w vm.max_map_count=262144
- sudo sysctl -w fs.inotify.max_user_watches=524288
script:
- npm run functional-test

notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/8e145155fbaaf37cffea
on_success: change
on_failure: always
on_start: never
email: false

slack:
rooms:
- secure: "qMcRdKvIcnc56pQsHBgRDOAMbpIwMNd/brT8Vib+iA96JVpZz4voehRbQ4n7qOZER7riA4eXorcOLZQ1m3M+vyx247LePnDA5w2TWFmKy9nc6KMefB4m6ZktSFMWS/4J4rdj+jivEYAsM+xIo489lukWa1Y463bkg5KdWapEbgaEE0Jv1X5nElkSwazuUcRVMr9iEt0sA6So5dUx9nvi7P9u+KBC7kchfdh15+a7fhTKH1AltkHalPweVEeqbLRnwWNV43+hRI6oIgnuPITY4+/bgh47V/SIEAdUSZoEtdz+PeiyNEYCPgvDPKf3C1lL1bhQURpt6qgaO2Ocu9dIa3ZrSe89gTK0SD0GI3cQlxA8ODp19au55EBumLxceuIIThnvSqb9QLjqYcILQpDG3mkki4VsipP7h1Zzg0bF8ysHSeaeqv+55aIJo7POx2wVM1YXW7qVugMov0bC9gyu72I8iwn7jTPE5NQT7NJfL3STOHGy75tXSzYLN6VwvdGKhQScroIgPbsO8rkdzZad9e1G2w/s1IpnawD7H2FY1Mrb+FMcg9JJ6oLY7rmkK6Ol1cBxAtTO7qPQ7/bE8hax5uLWFEd6+r5RGIPbk7UtKd43pXIos7ajuKxX+7ovkwmZ7mioEuMvRF1DJbiw7LWTe65W35h2o7B4OIflgg/zlPE="
on_success: never
on_failure: always

addons:
sonarqube: true
sonarcloud: true
159 changes: 120 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This plugin adds a cluster mode to Kuzzle.

## Compatibility

Kuzzle: >=1.4.0
Kuzzle: >=1.8.0

## Try it

Expand All @@ -16,28 +16,23 @@ To run a kuzzle stack, you can use the provided compose file:
docker-compose up --scale kuzzle=3
```

NB: This compose stack is for tests only and should not be used as-is on production.
Notably, only kuzzle runs in cluster mode, elasticsearch and redis are using one node only.
**NB: This compose stack is for tests and development only and should not be used as-is on production. **

## Run a development stack

The development stack mounts both kuzzle and the cluster sources as docker volumes.

```bash
cd <dir>
git clone -b <commit> [email protected]:kuzzleio/kuzzle.git
git clone [email protected]:kuzzleio/kuzzle-plugin-cluster.git
git clone https://github.com/kuzzleio/kuzzle-plugin-cluster.git

cd kuzzle-plugin-cluster
cp docker-compose/my.env.sample docker-compose/my.env
vim docker-compose/my.env

./dev-npm-install.sh
./dev.sh
```

You should now have a full Kuzzle clustered stack running 3 Kuzzle front nodes (and 3 servers).
Each update on either Kuzzle or the cluster source should automatically restart kuzzle.
Each update on the cluster source should automatically restart kuzzle.

**Note:** on some Linux environments, you may get `ENOSPC` errors from the filesystem watcher. If so, you need to raise the limits on the number of files that can be watched:

Expand All @@ -49,6 +44,27 @@ Each update on either Kuzzle or the cluster source should automatically restart
* `curl -XPOST http://localhost:7512/_plugin/cluster/reset` => resets redis state and force a new sync (blanks cluster state)
* `bash docker-compose/scripts/devtools.sh` dumps to the standard output the urls to copy/paste in Google Chrome to live-debug the nodes

## Run the cluster in production

### Install

The cluster needs to be installed as a plugin. Please refer to [Kuzzle documentation](https://docs.kuzzle.io/guide/1/essentials/plugins/#installing-a-plugin) on how to proceed.

### Network ports

By default, Kuzzle nodes communicate with each other using two channels on ports `7510` and `7511`.
**NB: These ports are used by the cluster only and do not need to be publicly exposed.**

You can configure the ports used in the `bindings` section of the plugin configuration (cf [below](#configuration)).

Each Kuzzle node also needs to be able to access Redis and Elasticsearch services.

### Healthcheck

The cluster exposes a healthcheck route on http://kuzzle:7512/_plugin/cluster/health

The route returns a 200 status code only if the `minimumNodes` set in the configuration is reached (cf [configuration](#configuration) below).

## Configuration

### Privileged context
Expand All @@ -57,7 +73,7 @@ This plugin needs privileged context to work. This context is granted by Kuzzle

```javascript
plugins: {
'cluster': {
cluster: {
privileged: true
}
}
Expand All @@ -78,6 +94,27 @@ Make sure you increase your pipe timeouts accordingly.
}
```

### Bindings

The bindings on which each node can be reached by the others can be configured in the `bindings` section of the cluster plugin configuration:

```json
"plugins": {
"cluster": {
"bindings": {
"pub": "tcp://[_site_:ipv4]:7511",
"router": "tcp://[_site_:ipv4]:7510"
}
}
}
```

The syntax is `tcp://[<interface>:<family>]:<port>`, where

- `interface` is either a network interface (i.e. `eth0`), an ip address (i.e. `0.0.0.0`) or `_site_`. If set to `_site_`, the first public ip will be used.
- `family` is either set to `ipv4` (default) or `ipv6`
- `port` is set to the port to listen to

### Redis cluster

Redis cluster comes with some limitations:
Expand All @@ -88,42 +125,86 @@ Redis cluster comes with some limitations:
The latter implies the configuration cannot be set via environment variables.
To comply with the former, make sure to set only one database index (0).

i.e.:
### Full configuration sample

Here is a complete sample configuration using a 3 nodes redis cluster and a 2 elasticsearch nodes.

```json
"internalCache": {
"database": 0,
"nodes": [
{
"host": "cluster_redis_1",
"port": 6379
},
{
"host": "cluster_redis_2",
"port": 6379
},
{
"host": "cluster_redis_3",
"port": 6379
}
]
"plugins": {
"common": {
"pipeWarnTime": 5000,
"pipeTimeout": 10000
},
"cluster": {
"privileged": true,
"bindings": {
"pub": "tcp://[_site_:ipv4]:7511",
"router": "tcp://[_site_:ipv4]:7510"
},
"memoryStorage": {
"database": 0,
"nodes": [
{
"host": "cluster_redis_1",
"port": 6379
},
"minimumNodes": 1,
"retryJoin": 30,
"timers": {
"discoverTimeout": 3000,
"joinAttemptIntervall": 2000,
"heartbeat": 5000,
"waitForMissingRooms": 4500
}
}
},

"services": {
"internalCache": {
"database": 0,
"nodes": [
{
"host": "redis1",
"port": 6379
},
{
"host": "redis2",
"port": 6379
},
{
"host": "redis3",
"port": 6379
}
]
},
"memoryStorage": {
"database": 0,
"nodes": [
{
"host": "redis1",
"port": 6379
},
{
"host": "redis2",
"port": 6379
},
{
"host": "redis3",
"port": 6379
}
]
},
"db": {
"client": {
"host": false,
"hosts": [
{
"host": "cluster_redis_2",
"port": 6379
"protocol": "http",
"host": "elasticsearch1",
"port": 9200
},
{
"host": "cluster_redis_3",
"port": 6379
"protocol": "http",
"host": "elasticsearch2",
"port": 9200
}
]
}
```
}
}

```

12 changes: 12 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
coverage:
range: "80...100"

status:
project:
default:
threshold: 1

patch:
default:
branches:
- master
7 changes: 5 additions & 2 deletions docker-compose/docker-compose.yml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ services:
DEBUG_COLORS: ${DOLLAR}{DEBUG_COLORS:-on}

redis:
build: ./redis
build:
context: ./redis
args:
- REDIS_VERSION=${DOLLAR}{REDIS_VERSION:-4.0}
command: redis-server /usr/local/etc/redis/redis.conf

redis_init_cluster:
Expand All @@ -36,7 +39,7 @@ services:
- redis

elasticsearch:
image: kuzzleio/elasticsearch:5.4.1
image: kuzzleio/elasticsearch:5.6.10
ulimits:
nofile: 65536
environment:
Expand Down
2 changes: 1 addition & 1 deletion docker-compose/images/kuzzle/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM kuzzleio/kuzzle
FROM kuzzleio/kuzzle:1-dev

RUN set -x \
\
Expand Down
14 changes: 0 additions & 14 deletions docker-compose/my.env.sample
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
# Docker image to use for Kuzzle core servers.
# Defaults to "kuzzleio/kuzzle"
# LB_IMAGE=kuzzleio/kuzzle

# If set, will mount the lb source from $LB_PATH directory
# LB_PATH=../../kuzzle-load-balancer

# If set, will mount the proxy sources in load balancer node_modules
# Else, will use the version defined in load-balancer packages.json
# PROXY_PATH=../../kuzzle-proxy

# DEBUG env var for the load balancer - Defaults to empty string (no debug)
# LB_DEBUG=kuzzle-proxy:load-balancer*

# If set, will mount Kuzzle source from $KUZ_PATH directory
# KUZ_PATH=../../kuzzle

Expand Down
3 changes: 3 additions & 0 deletions docker-compose/npm-install.yml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,7 @@ services:
cd /var/app
done
'
environment:
NODE_ENV: development


Loading

0 comments on commit 59430f5

Please sign in to comment.