Mam serwis internetowy, który korzysta z websockets, i muszę zrealizować wdrożenie z zerowym czasem oczekiwania. Ponieważ nie chcę usuwać istniejące połączenia podczas wdrażania, postanowiłem zrealizować wdrożenie niebieskiego/zielonego koloru. Moje rzeczywiste rozwiązanie wygląda tak:
- Stworzyłem dwie identyczne usługi w portainer, które wykrywają różne porty. Każda usługa ustaliła w środowiskach węzłów jakiś identyfikator, np.
alfa
ibeta
- Obie usługi są ukryte za балансировщиком obciążenia, i oficjalne okresowo sprawdzić stan każdej usługi. Jeśli usługa odpowiada na określoną trasę (/biblioteka-sprawdzanie aktywności) ciąg "OK", ta usługa jest aktywna, a biblioteka może wykonać trasowanie do tej usługi. Jeśli usługa odpowiada ciąg znaków "STOP", biblioteka oznacza tę usługę jako niedostępnej, ale aktywne połączenia zostaną zapisane
- jaka usługa jest aktywna, a jaka jest zatrzymana, synchronizacja przez redis. W redis ma klucze
lb.service.alfa
ilb.service.beta
który może zawierać wartości 1 do aktywnego i 0 dla nieaktywnych. Przykład realizacji /biblioteka-keepalive-sprawdzenie trasy w nestjs:
import {Controller, Get} from '@nestjs/common';
import {RedisClient} from "redis";
const { promisify } = require("util");
@Controller()
export class AppController {
private redisClient = new RedisClient({host: process.env.REDIS_HOST});
private serviceId:string = process.env.ID; //alfa, beta
@Get('balancer-keepalive-check')
async balancerCheckAlive(): Promise<string> {
const getAsync = promisify(this.redisClient.get).bind(this.redisClient);
return getAsync(`lb-status-${this.serviceId}`).then(status => {
const reply: string = status == 1 ? 'OK' : 'STOP';
return `<response>${reply}</response>`;
})
}
}
- w gitlab CI utwórz obraz docker oznaczone tagiem podczas zatwierdzenia, a następnie ponownie uruchom usługę, która wywołała webhook portainer dla danej usługi. To działa dobrze dla 1 usługi, ale nie wiem, jak korzystać z 2 różnych zmiennych CI DEPLOY_WEBHOOK i przełączać się między nimi.
image: registry.rassk.work/pokec/pokec-nodejs-build-image:p1.0.1
services:
- name: docker:dind
variables:
DOCKER_TAG: platform-websocket:$CI_COMMIT_TAG
deploy:
tags:
- dtm-builder
environment:
name: $CI_COMMIT_TAG
script:
- npm set registry http://some-private-npm-registry-url.sk
- if [ "$ENV_CONFIG" ]; then cp $ENV_CONFIG $PWD/.env; fi
- if [ "$PRIVATE_KEY" ]; then cp $PRIVATE_KEY $PWD/privateKey.pem; fi
- if [ "$PUBLIC_KEY" ]; then cp $PUBLIC_KEY $PWD/publicKey.pem; fi
- docker build -t $DOCKER_TAG .
- docker tag $DOCKER_TAG registry.rassk.work/community/$DOCKER_TAG
- docker push registry.rassk.work/community/$DOCKER_TAG
- curl --request POST $DEPLOY_WEBHOOK
only:
- tags
Moje pytania, na które nie wiem jak rozwiązać, są to:
- Gdy mam 2 usługi, mam 2 różne witryny wdrażania, z których muszę wywołać jeden po wdrożeniu, bo nie chcę ponownie uruchomić obie usługi. Jak ustalić, jaki dokładnie? Jak zrealizować jakiś licznik, jeśli to wdrożenie odnosi się do serwisu "alfa" lub "beta"? Czy muszę korzystać z api gitlab i aktualizować DEPLOY_WEBHOOK po każdym wdrażania? Czy muszę pozbyć się tej zmiennej gitlab CI/CD i użyć jakiegoś API w usługach, który poda mi adres URL-adres strony-haka?
- Jak zaktualizować wartości w redis? Czy muszę zrealizować użytkownika API do tego?
- Czy istnieje lepszy sposób aby to osiągnąć?
dodatkowe informacje: Nie mogę korzystać z api gitlab z usług, ponieważ nasz gitlab zamieszczona na domenie, dostępnym tylko z naszej sieci prywatnej.