반응형

https://doc.akka.io/docs/akka/current/typed/cluster-membership.html


https://getakka.net/articles/clustering/cluster-overview.html

 

Akka.Cluster Overview | Akka.NET Documentation

Akka.Cluster Overview What Is a "Cluster"? A cluster represents a fault-tolerant, elastic, decentralized peer-to-peer network of Akka.NET applications with no single point of failure or bottleneck. Akka.Cluster is the module that gives you the ability to c

getakka.net

 


Akka 클러스터 형성 과정은 클러스터가 올바르게 초기화되고 유지되도록 보장하기 위해 여러 주요 구성 요소와 단계를 포함한다. 다음은 클러스터가 형성되는 방법, 노드의 다양한 유형의 역할, 그리고 노드 상태 및 클러스터 무결성 관리 메커니즘에 대한 설명이다.

1. 시드 노드와 비시드 노드

  • 시드 노드(Seed Nodes): 잘 알려진 IP 주소/포트 조합을 가진 노드로, 클러스터 구성에서 미리 정의된다. 다른 노드가 클러스터에 가입할 때 초기 연락 점 역할을 한다.
  • 비시드 노드(Non-seed Nodes): 초기에는 주소가 알려지지 않은 노드로, 클러스터를 형성하기 위해 시드 노드에 연락해야 한다.

2. 초기 클러스터 형성

  • 클러스터는 시드 노드가 서로를 알고 있는 상태에서 시작한다. 예를 들어, A와 B 두 시드 노드가 있으면, 이 노드들은 서로의 존재를 인식하고 설정된다.
  • 비시드 노드(C, D, E와 같은)는 적어도 하나의 시드 노드에 연락할 수 있도록 구성된다.
  • 구성에서 첫 번째로 나열된 시드 노드는 반드시 작동 중이어야 한다.. 그렇지 않으면 클러스터가 형성되지 않는다. 이는 초기 시작 시 분산 브레인(scenarios) 같은 문제를 방지하기 위한 것이다.

3. 연결 설정

  • 비시드 노드는 지정된 시드 노드에 연결을 시도한다. 예를 들어, C와 D 노드는 A에, E 노드는 B에 연결하도록 설정될 수 있다.
  • 모든 노드는 클러스터 형성 과정을 시작하기 위해 시드 노드에 연결을 시도한다.

4. 리더 선출

  • 노드가 클러스터에 합류함에 따라 리더가 선출된다.. 리더는 일반적으로 시드 노드 중 하나이며, 클러스터 상태를 관리하는 책임이 있다.
  • 리더는 직접 통신할 수 있는 노드부터 시작하여 알고 있는 노드들을 활성 상태로 표시하기 시작한다.

5. 가십 프로토콜

  • 클러스터 멤버십에 대한 가십(gossip) 정보가 모든 노드에 퍼지기 시작한다. 이 정보에는 어떤 노드들이 활성화되어 있고 그들의 연결 상태가 포함된다.
  • 노드들은 지속적으로 통신을 하며, 각 노드가 다른 모든 노드와 연결된 메시 네트워크를 형성한다.

6. 클러스터 무결성 및 관리

  • 클러스터가 운영되는 동안, 노드들은 서로에게 지속적으로 하트비트를 보내 가용성을 확인한다. 하트비트를 충분히 보내지 못하면 노드는 동료들에 의해 접근 불가능하다고 표시된다.
  • 리더는 접근 불가능한 노드가 다시 접근 가능해지거나 공식적으로 클러스터에서 제거될 때까지 클러스터 결정을 중단한다. 클러스터의 상태가 일관되지 않은 경우 리더는 자신의 업무를 수행할 수 없다고 표시한다.

7. 노드 고장 및 퇴출 처리

  • 노드가 접근 불가능해지면 설정된 타임아웃(auto-down-unreachable-after)을 사용하여 노드를 영구적으로 제거(다운)하기로 결정할 수 있다.
  • 노드는 클러스터에서 우아하게 퇴출될 수도 있으며, 이는 노드가 접근 불가능하게 표시되는 것을 방지한다.

8. 조정된 종료

  • 노드가 클러스터에서 우아하게 종료할 수 있도록 조정된 종료 프로세스를 제공한다.

 

 

 

반응형

'개발관련 > ETC..' 카테고리의 다른 글

Git 커밋된 계정 기록 변경하기  (0) 2024.04.28
MMF(Memory Mapping File)  (0) 2024.03.18
Https 적용하기  (0) 2024.03.11
aws ec2 프리티어 메모리 부족  (0) 2023.09.22
Linux에 서비스 등록  (0) 2023.01.10
반응형

daemon.json 등록

sudo vi /etc/docker/daemon.json

 

호스트 입력

{
 "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
}

 

서비스를 확인한다.

sudo vi /lib/systemd/system/docker.service

 

서비스에 -H 플래그가 있다면 Daemon.json의 호스트와 충돌이 발생할 수 있다.

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

 

아래와 같이 제거를 한다.

ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock
반응형

'개발관련 > Docker' 카테고리의 다른 글

jenkins에서 도커 명령어 사용하기  (0) 2024.03.10
도커에 GitLab 설치 및 실행  (2) 2023.09.21
Docker 설치  (0) 2023.01.08
반응형
git filter-branch -f --env-filter '

UPDATE_NAME="username"
UPDATE_EMAIL="user@mailadress"

if [ "$GIT_COMMITTER_EMAIL" = "old@mail.com" ]
then
    export GIT_AUTHOR_NAME="$UPDATE_NAME"
    export GIT_COMMITTER_NAME="$UPDATE_NAME"
    export GIT_COMMITTER_EMAIL="$UPDATE_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "old@mail.com" ]
then
    export GIT_AUTHOR_NAME="$UPDATE_NAME"
    export GIT_COMMITTER_NAME="$UPDATE_NAME"
    export GIT_COMMITTER_EMAIL="$UPDATE_EMAIL"
fi
if [ "$GIT_COMMITTER_NAME" = "oldusername" ]
then
    export GIT_AUTHOR_NAME="$UPDATE_NAME"
    export GIT_COMMITTER_NAME="$UPDATE_NAME"
    export GIT_COMMITTER_EMAIL="$UPDATE_EMAIL"
fi
if [ "$GIT_AUTHOR_NAME" = "oldusername" ]
then
    export GIT_AUTHOR_NAME="$UPDATE_NAME"
    export GIT_COMMITTER_NAME="$UPDATE_NAME"
    export GIT_COMMITTER_EMAIL="$UPDATE_EMAIL"
fi

' --tag-name-filter cat -- --branches --tags

 

rebase를 통해서 하는 것보다 훨씬 더 수월하게 잘못 커밋된 계정을 변경할 수 있다.

 

git push -f

 

 

쌓인 커밋들을 다시 푸시하면 된다.

반응형

'개발관련 > ETC..' 카테고리의 다른 글

Akka 클러스터  (0) 2024.05.14
MMF(Memory Mapping File)  (0) 2024.03.18
Https 적용하기  (0) 2024.03.11
aws ec2 프리티어 메모리 부족  (0) 2023.09.22
Linux에 서비스 등록  (0) 2023.01.10
반응형

메모리 매핑 파일(Memory-Mapped File)은 파일이나 장치의 내용을 메모리 주소 공간에 매핑하는 기술이다. 이 방법을 사용하면 파일이나 장치의 데이터에 대한 접근을 마치 메모리에 직접 있는 데이터에 접근하는 것처럼 수행할 수 있다. 이는 데이터의 읽기와 쓰기 속도를 향상시킬 수 있으며, 대용량 파일 처리에 특히 유용하다.

메모리 매핑 파일을 이용한 프로세스 간 공유는 고성능의 IPC 메커니즘을 제공하며, 파일 입출력보다 훨씬 빠른 데이터 접근 속도를 가능하게 한다. 그러나 공유 데이터에 대한 동시 접근을 관리하는 것이 중요하며, 적절한 동기화 방법을 선택하여 데이터의 일관성과 무결성을 보장해야 한다.

 

작동 원리

  1. 매핑 생성: 운영 체제는 파일의 내용을 프로세스의 가상 메모리 주소 공간에 매핑한다. 이 과정에서 실제 물리 메모리의 할당은 필요한 부분이 실제로 접근될 때까지 지연된다.
  2. 데이터 접근: 프로그램은 메모리 주소를 통해 파일 데이터에 접근할 수 있게 된다. 이 때, 파일 내용은 메모리에 있는 것처럼 읽기, 쓰기, 수정이 가능하다.
  3. 변경 사항 반영: 메모리에 있는 데이터에 대한 변경 사항은 시스템에 의해 자동으로 파일에 반영된다. 이는 주기적으로 또는 메모리 매핑이 해제될 때 수행될 수 있다.

장점

  • 성능 향상: 메모리 매핑을 사용하면 파일 입출력(I/O) 연산이 메모리 접근 연산으로 대체된다. 이는 입출력 연산의 오버헤드를 줄이고 성능을 향상시킨다.
  • 간편한 데이터 접근: 배열이나 포인터를 사용해 직접 메모리에 접근하는 것처럼 파일 데이터에 접근할 수 있어, 복잡한 파일 입출력 코드를 단순화할 수 있다.
  • 대용량 파일 처리: 메모리 매핑은 파일 전체를 메모리에 로드하지 않고 필요한 부분만 로드하기 때문에, 사용 가능한 물리 메모리보다 큰 파일도 효율적으로 처리할 수 있다.

 

반응형

'개발관련 > ETC..' 카테고리의 다른 글

Akka 클러스터  (0) 2024.05.14
Git 커밋된 계정 기록 변경하기  (0) 2024.04.28
Https 적용하기  (0) 2024.03.11
aws ec2 프리티어 메모리 부족  (0) 2023.09.22
Linux에 서비스 등록  (0) 2023.01.10
반응형

SSL FOR FREE 사이트에 도메인을 입력하고 차례 차례 순서대로 입력한다.

90일 짜리 공짜

CName 입력
Name:
_95D1090C735AB2C3856848066F6C96C0 도메인을 제외하고 입력

별칭 :  824C3264FAF387913C281A2F7F799281.AA6016E7E6E327734C6A1CE3FA469BDF.bb884888ef31b52.comodoca.com 값을 그대로 입력한다.

 

 

Install Certificate 단계에서 해당 파일을 다운로드 받는다.

3개의 파일을 서버에 올린 후 합쳐준다.

cat certificate.crt ca_bundle.crt > combined.pem

 

docker compose 설정에 볼륨 경로를 연결한다.

  - type: bind
    source: ./certificate
    target: /etc/nginx/ssl

 

Nginx 설정파일(nginx.conf)

    # XXXXX.com을 위한 서버 블록
    server {
        listen 443 ssl;
        server_name XXXXX.com www.XXXXX.com;

        ssl_certificate /etc/nginx/ssl/combined.pem;
        ssl_certificate_key /etc/nginx/ssl/private.key;

        ssl_protocols TLSv1.2 TLSv1.3;

        location / {
            proxy_pass http://127.0.0.1:9100;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }

    # XXXXX.com을 위한 서버 블록
    server {
        listen 80;
        server_name XXXXX.com www.XXXXX.com;
        # HTTP 요청을 HTTPS로 리다이렉트
        return 301 https://$host$request_uri;
    }

 

반응형

'개발관련 > ETC..' 카테고리의 다른 글

Git 커밋된 계정 기록 변경하기  (0) 2024.04.28
MMF(Memory Mapping File)  (0) 2024.03.18
aws ec2 프리티어 메모리 부족  (0) 2023.09.22
Linux에 서비스 등록  (0) 2023.01.10
Non clustered Index, clustered Index  (0) 2022.12.20
반응형

보안상 좋지 않고 추천한다고는 하진 않지만 jenkins는 보통은 믿을 수 있는 사람들 접근할 수 있도록 하기에 문제는 없어보인다.

볼륨으로 Docker 명령어를 실행할 수 있도록 연결한다.

 

docker-compose.yml

version: '3.3'
services:
  jenkins:
    image: jenkins/jenkins:latest
    volumes:
      - type: bind
        source: ./home
        target: /var/jenkins_home
      - type: bind
        source: /var/run/docker.sock
        target: /var/run/docker.sock
      - type: bind
        source: /usr/bin/docker
        target: /usr/bin/docker
    ports:
      - "8080:8080"
      - "50000:50000"
    restart: always

 

 

반응형

'개발관련 > Docker' 카테고리의 다른 글

Daemon.json 호스트 설정시 트러블 슈팅  (0) 2024.05.12
도커에 GitLab 설치 및 실행  (2) 2023.09.21
Docker 설치  (0) 2023.01.08
반응형

Unity-iPhone

  • Build Settings
    • Build Options
      • Always Embed Swift Standard libraries = yes

UnityFramework

  • Build Settings
    • Build Options
      • Always Embed Swift Standard libraries = no

공통

  • BuildSetting
    • Build Options
      • Enable Bitcode = no

로 설정해준다.

 

 

 

반응형

'개발관련 > Unity' 카테고리의 다른 글

앱 이름 다국어 설정  (0) 2023.11.06
해상도 고정  (0) 2023.09.02
TextMeshPro 폰트 생성  (0) 2023.07.31
클리커 게임 단위 구하기  (0) 2023.03.15
Addressables 동기 사용법 및 주의점  (0) 2022.09.12
반응형

다국어 설정은 Localization 해당 패키지를 이용한다.

Localization 1.3.2 버전은 버그가 있기 때문에 1.4.3 버전으로 업그레이드 해야한다.

 

 

Localization Tables를 클릭한다.

Localization이란 폴더를 만들고 해당 폴더에 Localization Settings.asset을 저장한다.

그러면 아래의 화면이 뜨고 Locale Generator를 클릭합니다.

저는 한국어와 영어를 선택했습니다. 필요시에 추가적으로 언어를 선택합니다. Generate Locales 클릭합니다.

 

Create 버튼을 클릭합니다. 적당한 폴더를 설정해줍니다.

 

Add New Entry를 클릭하고 key에는 app_name을 입력

영어와 한글에 맞게 앱 이름을 설정합니다.

 

유니티 인스펙터에서 Localization 경로에 세팅한 Localization Settings 을 클릭합니다. 그리고 아래의 그림에 맞춰 + 버튼을 클릭합니다. 그리고 Android Appinfo를 클릭합니다.

 

Display Name을 클릭하면 등록한 app_name이 보입니다.

 

반응형

'개발관련 > Unity' 카테고리의 다른 글

xcode upload contain disallowed file 'Frameworks'  (0) 2023.11.09
해상도 고정  (0) 2023.09.02
TextMeshPro 폰트 생성  (0) 2023.07.31
클리커 게임 단위 구하기  (0) 2023.03.15
Addressables 동기 사용법 및 주의점  (0) 2022.09.12
반응형

리플렉션의 MethodInfo.Invoke는 속도가 많이 느리다.

이를 개선하기 위해서는 코드 제너레이터를 통하여 코드를 생성하는 방법과 델리게이트를 이용한 방법이 널리 알려져 있다.

method.CreateDelegate를 통하여 MethodInfo.Invoke 사용할 수도 있지만 이 방법은 객체가 생성이 된 후에 초기화가 가능하다.

.Net MVC에서 Controller는 표현식 트리(Expression Tree) 라는 것을 사용하여 리플렉션의 느린 속도를 개선하였다.

 

표현식 트리는 코드의 구조와 동작을 표현하는 데이터 구조이다. 주로 코드의 구문 분석, 변환, 또는 표현을 위해 사용된다.

 

Expression.Parameter: 메서드나 생성자에서 사용될 파라미터를 정의한다.
Expression.Call: 다른 메서드를 호출하는 표현식을 생성한다.
Expression.Lambda<Action<AA>>(methodCall, aaParam).Compile(): 표현식 트리를 델리게이트로 변환하고 컴파일한다.

이러한 방식으로 구성된 아래 코드는 MethodInfo invoke에 비해 훨씬 빠른 실행 속도를 보여준다.

 

using System;
using System.Diagnostics;
using System.Linq.Expressions;

namespace ConsoleApp
{
    public class AA
    {
        private int _index = 0;
        public void Call()
        {
            //Console.WriteLine($"{_index++}");
        }
    }

    class Program
    {
        delegate void CallDelegate();
        static void Main(string[] args)
        {
            var aaType = typeof(AA);
            var method = aaType.GetMethod("Call");
            Stopwatch sw = new Stopwatch();

            var a = new AA();
            sw.Reset();
            sw.Start();
            for (int i = 0; i < 100000; ++i)
            {
                a.Call();
            }
            sw.Stop();
            Console.WriteLine($"Direct call : {sw.Elapsed}");

            var b = new AA();
            sw.Reset();
            sw.Start();
            for (int i = 0; i < 100000; ++i)
            {
                method.Invoke(b, null);
            }
            sw.Stop();
            Console.WriteLine($"MethodInfo call : {sw.Elapsed}");

            // Delegate call
            var c = new AA();
            CallDelegate callDelegate = (CallDelegate)method.CreateDelegate(typeof(CallDelegate), c);
            sw.Reset();
            sw.Start();
            for (int i = 0; i < 100000; ++i)
            {
                callDelegate();
            }
            sw.Stop();
            Console.WriteLine($"Delegate call : {sw.Elapsed}");

            var aaParam = Expression.Parameter(aaType, "instance");
            var methodCall = Expression.Call(aaParam, method);
            var actionLambda = Expression.Lambda<Action<AA>>(methodCall, aaParam).Compile();

            var d = new AA();
            sw.Reset();
            sw.Start();
            for (int i = 0; i < 100000; ++i)
            {
                actionLambda(d);
            }
            sw.Stop();
            Console.WriteLine($"Expression call : {sw.Elapsed}");

            Console.ReadLine();
        }
    }
}

예시) 상속받은 클래스의 Event를 리플렉션으로 탐색하고 캐시하여 RaiseEvent 메소드 호출시 자동으로 Event 호출 까지 실행해준다.

public abstract class EventProtocolHandlerBase
{
    private readonly Dictionary<Type, Action<INotifyEventArgs>> _eventHandlers = new Dictionary<Type, Action<INotifyEventArgs>>();
    public EventProtocolHandlerBase()
    {
        RegisterEvents(GetType());
    }
    public void RaiseEvent<T>(T eventArgs) where T : INotifyEventArgs
    {
        if (_eventHandlers.TryGetValue(typeof(T), out var handler))
        {
            if (handler is Action<T> action)
            {
                Add(() => { action(eventArgs); });
            }
        }
        else
        {
            LogHelper.Error($"not found event type! {typeof(T).Name}");
        }
    }
    public void RegisterEvents(Type type)
    {
        foreach (var eventInfo in type.GetEvents())
        {
            var argumentType = eventInfo.EventHandlerType.GetGenericArguments()[0];
            var eventParameter = Expression.Parameter(typeof(INotifyEventArgs), "args");
            var castArg = Expression.TypeAs(eventParameter, argumentType);

            var eventFieldExpr = Expression.Field(Expression.Constant(this), eventInfo.Name);
            var invokeExpr = Expression.Invoke(eventFieldExpr, castArg);

            var notNullCheck = Expression.NotEqual(eventFieldExpr, Expression.Constant(null, typeof(Action<>).MakeGenericType(argumentType)));
            var conditionalExpr = Expression.IfThen(notNullCheck, invokeExpr);
            var lambda = Expression.Lambda<Action<INotifyEventArgs>>(conditionalExpr, eventParameter);
            var action = lambda.Compile();
            RegisterEvent(argumentType, action);
        }
    }
    public void RegisterEvent(Type type, Action<INotifyEventArgs> action)
    {
        _eventHandlers[type] = action;
    }
}
반응형
반응형

https://repost.aws/ko/knowledge-center/ec2-memory-swap-file

 

스왑 파일을 사용하여 Amazon EC2 인스턴스의 스왑 공간으로 메모리 할당

Amazon Elastic Compute Cloud(Amazon EC2) 인스턴스에서 스왑 파일로 사용할 메모리를 할당하려고 합니다. 어떻게 해야 하나요?

repost.aws

t2.micro 유형에 도커를 통하여 Gitlab을 설치를 하게 되면 터미널이 끊어지고 EC2가 뻗어버리는 현상이 발생한다.

이는 t2.micro RAM이 1GB 밖에 지원하지 않기 때문이다.

이 문제를 해결하려면 스왑 메모리를 고려해볼 수 있다. 스왑 메모리는 주 메모리(RAM)가 부족할 때 하드 드라이브나 SSD의 일부를 임시 메모리로 사용하여 부족한 메모리를 대체할 수 있다.

다만 디스크 I/O가 증가할 수 있으므로 성능에 단점이 발생할 수 있다.

 

Swap Memory 설정 방법

RAM의 크기에 따라서 Swap Memory 사이즈를 정한다.


RAM이 2GB 이하인 경우: RAM 크기의 2배.
RAM이 2GB~8GB인 경우: RAM 크기와 동일.
RAM이 8GB 이상인 경우: 필요에 따라 RAM 크기의 0.5배 ~ 1배.

 

1.EC2 t2.micro 유형은 1GB 바이트이기 때문에 Swap Memory 사이즈를 2GB로 정한다.

sudo dd if=/dev/zero of=/swapfile bs=128M count=16

2.Swap 파일의 읽기 및 쓰기 권한을 업데이트한다.

sudo chmod 600 /swapfile

3.Swap 영역을 설정합니다.

sudo mkswap /swapfile

 

4.Swap 공간에 스왑 파일을 추가하여 Swap 파일을 즉시 사용할 수 있도록 한다.

sudo swapon /swapfile

5./etc/fstab 파일을 편집하여 부팅 시 Swap 파일을 시작합니다.

sudo vi /etc/fstab

파일 끝에 다음 줄을 새로 추가하고 파일을 저장한 다음 종료합니다.

/swapfile swap swap defaults 0 0

6.free 명령어로 메모리 상태를 확인하면 된다.

 

반응형

'개발관련 > ETC..' 카테고리의 다른 글

MMF(Memory Mapping File)  (0) 2024.03.18
Https 적용하기  (0) 2024.03.11
Linux에 서비스 등록  (0) 2023.01.10
Non clustered Index, clustered Index  (0) 2022.12.20
Apple revoke token 처리  (0) 2022.07.09

+ Recent posts