에임에서의 기록 백업
This commit is contained in:
parent
be892052e2
commit
4bafee36ee
|
|
@ -1,16 +0,0 @@
|
||||||
- **Obsidian Vault (Private Repo):** 개인용 비공개 저장소에 마스킹되지 않은 원본 노트를 push합니다.
|
|
||||||
|
|
||||||
- **Jenkins Trigger:** 젠킨스가 Webhook을 통해 push 이벤트를 감지하거나 주기적으로 폴링(Polling)합니다.
|
|
||||||
|
|
||||||
- **Validation & Masking (Build Step):** 젠킨스 서버 내에서 Python 스크립트 등을 실행해 변경된 파일의 민감 정보를 검증하고 수정합니다.
|
|
||||||
|
|
||||||
- **Push to Quartz (Post-build):** 정제된 파일을 쿼츠 저장소로 복사한 뒤, 해당 저장소에 커밋 및 push를 수행합니다.
|
|
||||||
|
|
||||||
> [!todo] **필요한것** 📋
|
|
||||||
>
|
|
||||||
> - [x] kui vault repository
|
|
||||||
> - [x] kui repository
|
|
||||||
> - [ ] Jenkins 서버 ( 구글에서 제공해주는 클라우드 서버 확보하면 될 듯 )
|
|
||||||
> - [ ] blur 처리 용 서버 ( kui veil, veil 이라고 이름 지으면 될 듯 )
|
|
||||||
|
|
||||||
jenkins 서버를 구성해보자
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
확보중인 개인용 서버가 없기 때문에 서버부터 확보해야 함.
|
|
||||||
|
|
||||||
> [!question]
|
|
||||||
> Q. 클라우드 서버를 확보해야해. 무료여야하고 지금 내가 하려는 블러처리작업용으로 적당한정도면 돼
|
|
||||||
> A. 무료이면서 **젠킨스**와 **마스킹 스크립트(Python)**를 돌리기에 가장 적합한 클라우드 서비스 3가지를 추천해 드릴게요. 2026년 현재 기준으로도 가장 안정적인 옵션들입니다.
|
|
||||||
|
|
||||||
|**비교 항목**|**Oracle Cloud**|**Google Cloud**|**AWS**|
|
|
||||||
|---|---|---|---|
|
|
||||||
|**성능 (RAM)**|⭐⭐⭐⭐⭐ (24GB)|⭐ (1GB)|⭐⭐ (2GB)|
|
|
||||||
|**안정성**|⭐⭐⭐|⭐⭐⭐⭐⭐|⭐⭐⭐⭐⭐|
|
|
||||||
|**추천 이유**|젠킨스 구동에 여유로움|설정이 매우 간편함|글로벌 표준 학습 가능|
|
|
||||||
이 중 AWS는 일정기간만 무료임
|
|
||||||
오라클은 아직 마이너해서 쓰고싶지 않음
|
|
||||||
GCP로 가기로 함.
|
|
||||||
Google Cloud Platform
|
|
||||||
|
|
||||||
---
|
|
||||||
구글 클라우드(GCP)에서 **평생 무료**로 쓸 수 있는 사양은 딱 하나 정해져 있습니다. 바로 **e2-micro** 인스턴스입니다. 실시간 응답이 중요하지 않은 **`kui-ink`** 서버용으로는 아주 적절한 선택이에요.
|
|
||||||
|
|
||||||
GCP에서 무료로 구동하기 위한 '필수 조건'을 정리해 드릴게요. 이대로만 설정하면 돈이 나가지 않습니다.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 🖥️ GCP 평생 무료 서버 설정값 (2026 기준)
|
|
||||||
|**항목**|**설정해야 할 값**|**비고**|
|
|
||||||
|---|---|---|
|
|
||||||
|**리전 (Region)**|**us-west1** (오리건)|한국에서 가장 지연시간이 적은 무료 리전|
|
|
||||||
|**머신 유형**|**e2-micro**|2 vCPU, 1GB RAM (공유 코어)|
|
|
||||||
|**부팅 디스크**|**Standard** Persistent Disk|'Balanced'나 'SSD'는 유료입니다!|
|
|
||||||
|**디스크 용량**|**30GB** 이하|무료 한도가 딱 30GB까지입니다.|
|
|
||||||
### ⚠️ 주의할 점 (젠킨스 구동 관련)
|
|
||||||
|
|
||||||
**e2-micro**는 램이 **1GB**뿐입니다. 젠킨스는 Java 기반이라 기본적으로 메모리를 많이 먹어서, 그냥 실행하면 서버가 멈출 수도 있어요. 이를 해결하기 위한 팁입니다.
|
|
||||||
|
|
||||||
1. **Swap 메모리 설정:** 부족한 램을 보충하기 위해 하드디스크의 일부(약 2GB)를 가상 메모리로 사용하는 설정을 반드시 해줘야 합니다.
|
|
||||||
|
|
||||||
2. **경량화 설정:** 젠킨스 실행 옵션에서 사용할 메모리 최대치(`-Xmx`)를 제한하면 1GB 환경에서도 꾸역꾸역 돌아갑니다.
|
|
||||||
|
|
||||||
3. **오리건 리전:** 앞서 말씀드린 것처럼 한국 리전은 무료가 아니므로 꼭 **us-west1**을 선택하세요.
|
|
||||||
|
|
||||||
### 🚀 다음 단계: 서버 생성하기
|
|
||||||
|
|
||||||
GCP 콘솔에 접속해서 아래 순서대로 진행해 보세요.
|
|
||||||
|
|
||||||
1. [GCP 콘솔](https://console.cloud.google.com/) 접속 및 프로젝트 생성
|
|
||||||
|
|
||||||
2. **Compute Engine > VM 인스턴스** 메뉴로 이동
|
|
||||||
|
|
||||||
3. **인스턴스 만들기** 클릭
|
|
||||||
|
|
||||||
4. 위에 표에 적힌 **리전, 머신 유형, 디스크**를 정확히 선택
|
|
||||||
|
|
||||||
5. 하단 **만들기** 버튼 클릭
|
|
||||||
|
|
||||||
|
|
||||||
혹시 가입이나 인스턴스 생성 중에 막히는 부분이 생기면 바로 말씀해 주세요. 서버가 만들어지면 바로 **`kui-ink`**라는 이름을 붙여주고 젠킨스 설치로 넘어가겠습니다!
|
|
||||||
|
|
||||||
**지금 바로 GCP 가입을 시도해 보시겠어요?** 가입 후 서버 생성 화면까지 가시면 다음 가이드를 드릴게요.
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
를 시도했지만 실패함.
|
|
||||||
아마 우분투 최신버전 (25. 몇이었는데..)과 젠킨스가 잘 안맞는거 같음.
|
|
||||||
|
|
||||||
젠킨스말고 다른 우회방법을 찾아봄
|
|
||||||
|
|
||||||
> [!question]
|
|
||||||
> Q. 젠킨스를 대체할만한 프로그램없어?
|
|
||||||
> A. 젠킨스의 그 복잡한 설정과 인증 오류 때문에 정말 정이 뚝 떨어지셨을 것 같습니다. 180°C의 열정으로 시작했는데 도구 설치부터 막히면 누구라도 다른 길을 찾고 싶어지죠.
|
|
||||||
>
|
|
||||||
> **HDI**님이 원하시는 건 **내 서버(GCP) 내에서 직접 돌아가면서**, 젠킨스처럼 UI도 있고, 내 Obsidian 노트를 Quartz로 빌드해 배포해줄 **'설치가 쉽고 가벼운'** 대체 프로그램이겠죠?
|
|
||||||
>
|
|
||||||
> 젠킨스의 무거운 Java 기반 엔진 대신, 요즘 개발자들 사이에서 **젠킨스 킬러**로 불리는 가벼운 도구 2가지를 추천해 드립니다.
|
|
||||||
|
|
||||||
### 🛠️ 젠킨스를 대체할 가벼운 CI/CD 도구 TOP 2
|
|
||||||
|
|
||||||
#### 1. [[Woodpecker]] CI (강력 추천)
|
|
||||||
|
|
||||||
젠킨스가 대형 버스라면, [[Woodpecker]]는 날렵한 전기차 같습니다. **Go 언어**로 만들어져서 메모리를 아주 적게 먹고, 설정이 매우 직관적입니다.
|
|
||||||
|
|
||||||
- **장점:** 젠킨스보다 훨씬 가볍습니다(1GB 램인 `e2-micro`에 최적). 모든 설정을 `.woodpecker.yml` 파일 하나로 끝낼 수 있습니다.
|
|
||||||
|
|
||||||
- **UI:** 젠킨스처럼 깔끔한 웹 대시보드를 제공합니다.
|
|
||||||
|
|
||||||
- **설치:** 도커(Docker)를 이용하면 명령어 한두 줄로 끝납니다. 아까 같은 `GPG` 오류와 싸울 필요가 없습니다.
|
|
||||||
|
|
||||||
|
|
||||||
#### 2. Gitea Actions (Gitea를 쓰신다면 최고)
|
|
||||||
|
|
||||||
만약 내 서버에 소스코드를 직접 관리하고 싶다면 **Gitea**를 설치하는 방법이 있습니다. Gitea 안에는 GitHub Actions와 거의 똑같은 방식의 **Actions** 기능이 내장되어 있습니다.
|
|
||||||
|
|
||||||
- **장점:** 소스코드 관리(Git)와 자동 배포(CI/CD)를 한 곳에서 끝낼 수 있습니다.
|
|
||||||
|
|
||||||
- **특징:** GitHub Actions 문법을 그대로 쓸 수 있어 학습 곡선이 낮습니다.
|
|
||||||
|
|
||||||
### 💡 왜 이 도구들이 젠킨스보다 나을까요?
|
|
||||||
|
|
||||||
젠킨스는 20년 전 기술이라 설치 과정부터 수많은 의존성(Java 버전, GPG 키 등)과 싸워야 합니다. 반면 **Woodpecker** 같은 최신 도구들은 **도커(Docker)** 기반으로 돌아가는 것을 기본으로 합니다.
|
|
||||||
|
|
||||||
**도커를 사용하면:**
|
|
||||||
|
|
||||||
1. 내 서버의 우분투 버전이 무엇이든 상관없습니다.
|
|
||||||
|
|
||||||
2. `GPG` 키 에러, `NO_PUBKEY` 에러 같은 지긋지긋한 문제에서 완전히 해방됩니다.
|
|
||||||
|
|
||||||
3. 삭제하고 싶을 때도 명령어 한 줄이면 찌꺼기 없이 사라집니다.
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 🚀 HDI님을 위한 새로운 제안
|
|
||||||
|
|
||||||
**"도커(Docker)를 먼저 깔고, 그 위에 Woodpecker CI를 올려보는 건 어떠신가요?"**
|
|
||||||
|
|
||||||
도커는 설치가 아주 쉽고, 한 번 깔아두면 나중에 다른 프로그램을 올릴 때도 지금 같은 고생을 안 하게 해주는 마법 같은 도구입니다. 180°C의 집념을 젠킨스와의 싸움이 아닌, **진짜 자동화 시스템 구축**에 쏟으실 수 있게 도와드릴게요.
|
|
||||||
|
|
||||||
|
|
||||||
# 그래서 [[Woodpecker]] CI를 사용해보기로 함
|
|
||||||
docker 기반으로 구동되는 CI/CD tool
|
|
||||||
도커 기반이니까 당연히 os 안탈거같다
|
|
||||||
|
|
||||||
|
|
@ -1,117 +0,0 @@
|
||||||
## 1. 개요
|
|
||||||
|
|
||||||
기존 젠킨스(Jenkins)는 자바 기반으로 메모리 점유율이 높아 저사양 서버에서 구동이 힘들었음. 이를 해결하기 위해 Go 언어 기반의 초경량 CI 도구인 **Woodpecker**를 도입하고, 도커(Docker) 기반으로 환경을 재구축함.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. 환경 정화 및 도커 설치
|
|
||||||
|
|
||||||
무거운 자바를 삭제하고 현대적인 컨테이너 환경을 준비함.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# OpenJDK 삭제 및 정리
|
|
||||||
sudo apt purge -y openjdk-17-jre openjdk-17-jre-headless
|
|
||||||
sudo apt autoremove -y
|
|
||||||
|
|
||||||
# 도커(Docker) 설치
|
|
||||||
curl -fsSL https://get.docker.com -o get-docker.sh
|
|
||||||
sudo sh get-docker.sh
|
|
||||||
|
|
||||||
# 현재 사용자에게 도커 권한 부여
|
|
||||||
sudo usermod -aG docker $USER
|
|
||||||
newgrp docker # 로그아웃 없이 권한 즉시 적용
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. GitHub OAuth 앱 등록
|
|
||||||
|
|
||||||
우드패커가 GitHub 저장소에 접근할 수 있도록 통행증을 발급함.
|
|
||||||
|
|
||||||
1. **GitHub Settings > Developer settings > OAuth Apps** 이동
|
|
||||||
|
|
||||||
2. **New OAuth App** 생성
|
|
||||||
|
|
||||||
- Homepage URL: `http://34.19.79.94:8000`
|
|
||||||
|
|
||||||
- Authorization callback URL: `http://34.19.79.94:8000/authorize`
|
|
||||||
|
|
||||||
3. **Client ID**와 **Client Secret** 발급 및 보관
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. 우드패커 서버 및 에이전트 배포
|
|
||||||
|
|
||||||
`docker-compose`를 사용하여 서버(두뇌)와 에이전트(일꾼)를 동시에 띄움.
|
|
||||||
|
|
||||||
**파일 위치:** `~/woodpecker/docker-compose.yaml`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
services:
|
|
||||||
woodpecker-server:
|
|
||||||
image: woodpeckerci/woodpecker-server:latest
|
|
||||||
ports:
|
|
||||||
- 8000:8000
|
|
||||||
volumes:
|
|
||||||
- ./woodpecker-server:/var/lib/woodpecker
|
|
||||||
environment:
|
|
||||||
- WOODPECKER_OPEN=true
|
|
||||||
- WOODPECKER_HOST=http://34.19.79.94:8000
|
|
||||||
- WOODPECKER_AGENT_SECRET=wp_secure_9827_vpx_qr # 보안을 위해 이니셜 제외
|
|
||||||
- WOODPECKER_GITHUB=true
|
|
||||||
- WOODPECKER_GITHUB_CLIENT=발급받은_ID
|
|
||||||
- WOODPECKER_GITHUB_SECRET=발급받은_Secret
|
|
||||||
|
|
||||||
woodpecker-agent:
|
|
||||||
image: woodpeckerci/woodpecker-agent:latest
|
|
||||||
command: agent
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
environment:
|
|
||||||
- WOODPECKER_SERVER=woodpecker-server:9000
|
|
||||||
- WOODPECKER_AGENT_SECRET=wp_secure_9827_vpx_qr
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 실행 및 상태 확인
|
|
||||||
docker compose up -d
|
|
||||||
docker ps
|
|
||||||
```
|
|
||||||
|
|
||||||
## 5. 파이프라인 설정 (`.woodpecker.yml`)
|
|
||||||
|
|
||||||
저장소 최상단에 작업 지시서를 작성하여 자동화를 테스트함.
|
|
||||||
|
|
||||||
**주요 해결 과제:**
|
|
||||||
|
|
||||||
- **Git 명령 인식:** 기본 `alpine` 이미지에는 git이 없으므로 `alpine/git` 이미지를 사용하여 해결.
|
|
||||||
|
|
||||||
- **이력 확인(HEAD^):** 기본 clone은 depth가 1이라 이전 이력이 없음. `depth: 2` 설정을 통해 최적화된 상태로 이전 커밋과 비교 가능하게 함.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kind: pipeline
|
|
||||||
name: check-updates
|
|
||||||
|
|
||||||
clone:
|
|
||||||
setup:
|
|
||||||
image: woodpeckerci/plugin-git
|
|
||||||
settings:
|
|
||||||
depth: 2
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: show-changes
|
|
||||||
image: alpine/git
|
|
||||||
commands:
|
|
||||||
- echo "새로운 업데이트가 감지되었습니다!"
|
|
||||||
- echo "수정된 파일 목록:"
|
|
||||||
- git diff --name-only HEAD^ HEAD
|
|
||||||
- echo "최근 커밋 메시지:"
|
|
||||||
- git log -1 --pretty=%B
|
|
||||||
```
|
|
||||||
|
|
||||||
## 6. 트러블슈팅 기록
|
|
||||||
|
|
||||||
- **Forge Not Configured:** GitHub OAuth 설정이 누락되어 서버가 실행 직후 종료됨 -> 환경 변수 추가로 해결.
|
|
||||||
|
|
||||||
- **Agent Auth Error:** 서버 데이터베이스와 에이전트의 Secret Key가 꼬임 -> 서버 볼륨 삭제 후 재시작으로 초기화 성공.
|
|
||||||
|
|
||||||
- **GCP 방화벽:** 8000번 포트가 막혀 접속 불가 -> VPC 네트워크 방화벽 규칙 추가로 해결.
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
이 서비스의 핵심 기능을 해줄 weaver 서비스를 구현해야 함.
|
|
||||||
( 실제 blur 처리를 진행해줄 서비스 )
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
id: "kui-vault 20260401"
|
||||||
|
created: "2026-04-01 14:59"
|
||||||
|
tags:
|
||||||
|
---
|
||||||
|
**Google Cloud Platform(GCP)** 를 사용해서 구축함.
|
||||||
|
### 컴퓨팅 (Compute)
|
||||||
|
|
||||||
|
사용자가 코드를 실행할 공간을 제공합니다.
|
||||||
|
|
||||||
|
- **Compute Engine (GCE):** 가상 머신(VM)을 직접 생성하고 관리하는 IaaS 서비스입니다. (AWS의 EC2와 유사)
|
||||||
|
|
||||||
|
GCE를 한대 빌려서 구축하였음
|
||||||
|
![[Pasted image 20260401150036.png]]
|
||||||
|
원래는 퍼블릭하게 공개되면 안되는 자료들을 블러처리해주는 서버를 만들려고 (kui-veil) 확보한 서버였음
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -0,0 +1,9 @@
|
||||||
|
JVM이 메모리를 자동으로 관리해주는 것은 개발자의 입장에서 상당한 메리트이다.
|
||||||
|
|
||||||
|
하지만 문제는 GC를 수행하기 위해 Stop The World가 발생되고 이 때문에 애플리케이션이 중지되는 문제점이 발생하게 됭써다.
|
||||||
|
|
||||||
|
또한 자바가 발전됨에 따라 Heap의 사이즈가 커지면서 애플리케이션의 지연(Suspend) 현상이 두드러지게 되었고, 이를 최적화 위해 다양한 Garbage Collection(가비지 컬렉션) 알고리즘이 개발 되었다.
|
||||||
|
|
||||||
|
![[GC Algorithm 종류.png]]
|
||||||
|
|
||||||
|
알고리즘 종류
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
- 자바 옵션에 `-verbosegc` 라는 옵션을 주면 되고, `>` 리다이렉션 명령어를 통해서 파일로 저장하고 분석할 수 있다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
java -jar -verbosegc app.jar
|
||||||
|
```
|
||||||
|
|
||||||
|
Eclipse에서 찍는 방법
|
||||||
|
```ruby
|
||||||
|
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:D:\log\gclog\gclog.log
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
"할당 실패"는 GC 주기가 시작되는 원인입니다.
|
||||||
|
|
||||||
|
"할당 실패"는 Eden에 객체를 할당할 공간이 더 이상 남아 있지 않음을 의미합니다. 따라서 이는 ***Young GC의 정상적인 원인***입니다.
|
||||||
|
|
||||||
|
이전 JVM은 사소한 GC 주기에 대한 GC 원인을 인쇄하지 않았습니다.
|
||||||
|
|
||||||
|
"할당 실패"는 마이너 GC의 원인일 수 있는 거의 유일한 원인입니다. 마이너 GC가 발생하는 또 다른 이유는 CMS 설명 단계(+XX:+ScavengeBeforeRemark가 활성화된 경우) 때문일 수 있습니다.
|
||||||
|
|
||||||
|
"Allocation Failure" is a cause of GC cycle to kick in.
|
||||||
|
|
||||||
|
"Allocation Failure" means that no more space left in Eden to allocate object. So, it is normal cause of young GC.
|
||||||
|
|
||||||
|
Older JVM were not printing GC cause for minor GC cycles.
|
||||||
|
|
||||||
|
"Allocation Failure" is almost only possible cause for minor GC. Another reason for minor GC to kick could be CMS remark phase (if `+XX:+ScavengeBeforeRemark` is enabled).
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
![[GC Log 읽는법.png]]
|
||||||
|
|
||||||
|
[gceasy.io](http://gceasy.io/)등의 사이트를 이용하면 GC로그를 분석해 시각화 해주는 기능을 이용할 수있다!
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
### Gc tuning 절차 간단히 맛보기
|
||||||
|
|
||||||
|
[[GC]] 상황을 모니터링하며 현재 운영되는 시스템의 GC 상황을 확인한다.
|
||||||
|
```bash
|
||||||
|
# jstat gcutil 명령어로 현재 실행중인 8884번 프로세스에 대해 1초에 한번 씩 총 10번 GC와 관련된 정보를 출력하도록 모니터링
|
||||||
|
jstat -gcutil -t 8844 1000 0
|
||||||
|
```
|
||||||
|
|
||||||
|
![[jstat.png]]
|
||||||
|
|
||||||
|
| 컬럼 | 설명 |
|
||||||
|
| ---- | -------------------------------- |
|
||||||
|
| S0 | Survivor 영역 0의 사용율(현재 용량에 대한 비율) |
|
||||||
|
| S1 | Survivor 영역 1의 사용율(현재 용량에 대한 비율) |
|
||||||
|
| E | Eden 영역의 사용율 (현재 용량에 대한 비율) |
|
||||||
|
| O | Old 영역의 사용율 (현재 용량에 대한 비율) |
|
||||||
|
| P | Permanent 영역의 사용율 (현재 용량에 대한 비율) |
|
||||||
|
| YGC | Young 세대의 GC 이벤트 수 |
|
||||||
|
| YGCT | Young 세대의 GC 시간 |
|
||||||
|
| FGC | Full GC 이벤트 수 |
|
||||||
|
| FGCT | Full GC 시간 |
|
||||||
|
| GCT | GC 총 시간 |
|
||||||
|
|
||||||
|
#### **2.** **모니터링 결과 분석 후 GC 튜닝 여부 결정**
|
||||||
|
|
||||||
|
GC 상황을 확인한 후에는, 결과를 분석하고 GC 튜닝 여부를 결정해야 한다.
|
||||||
|
|
||||||
|
- **Minor GC 수행시간** : YGCT / YGC (0.314 / 19) = 0.016초
|
||||||
|
- **Major GC 수행 시간** : FGCT / FGC (0.291 / 3) = 0.097초
|
||||||
|
|
||||||
|
![[jstat 2.png]]
|
||||||
|
|
||||||
|
만약 모니터링 결과가 다음의 조건에 모두 부합한다면, GC 튜닝이 굳이 필요하지는 않다.
|
||||||
|
|
||||||
|
- Minor GC의 처리 시간이 빠르다 (50ms 내외)
|
||||||
|
- Minor GC의 주기가 빈번하지 않다 (10초 내외)
|
||||||
|
- Full GC의 처리 시간이 빠르다 (1초 내외)
|
||||||
|
- Full GC의 주기가 빈번하지 않다 (10분에 1회)
|
||||||
|
|
||||||
|
#### **3.** **GC 알고리즘 방식 지정**
|
||||||
|
|
||||||
|
위의 모니터링 결과를 보고, GC 튜닝을 진행하기로 결정했다면 GC 알고리즘 방식을 선정한다.
|
||||||
|
|
||||||
|
이때 서버가 여러 대이면 서버에 GC 옵션들을 서로 다르게 각각 지정해서, 현재 내 어플리케이션의 GC 알고리즘에 따른 차이를 확인하는 것이 좋다. (알고리즘이 더 최신이라고 해서 반드시 내 어플리케이션에서 해당 GC 방식이 적절하다라고 보증 할수 없다)
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
[[GC Algorithm]]
|
||||||
|
[[Parallel GC]]
|
||||||
|
- **'처리량'이 중요한 시스템에서 주로 사용** <br>- Full GC 수행 시 compaction 작업이 수행되기 때문에 GC 시간 자체는 많이 소요되나 일정한 멈춤 시간을 제공함|
|
||||||
|
CMS GC|
|
||||||
|
- **응답시간이 중용한 시스템에사 주로 사용** <br>- compaction 미수행으로 Stop-The-World 시간은 짧으나 자주 Compaction이 발생하는 시스템의 경우 오히려 Full GC 보다 Compation 시간이 오래 걸릴 수 있음 <br>- 자원 사용량이 증가하는 점도 고려해야 함|
|
||||||
|
G1 GC|
|
||||||
|
- 성능적으로 가장 우수한 GC 방식이나, JDK 7 버전부터 정식 제공되었으며, Java 9 에서 Default GC 방식으로 채택|
|
||||||
|
#### **4. 힙 메모리 크기 지정**
|
||||||
|
|
||||||
|
[[JVM Heap Area]]는 크기에 따라 GC 발생 횟수와 수행 시간에 영향을 끼치기 때문에 옵션을 통해 조절하면 어플리케이션 성능 향상 효과를 가져올 수 있다.
|
||||||
|
|
||||||
|
여기서 말하는 메모리 크기는 JVM의 시작 크기(-Xms)와 최대 크기(-Xmx)를 말한다.
|
||||||
|
[[Xms, Xmx]]
|
||||||
|
|
||||||
|
메모리 크기와 GC 발생 횟수, GC 수행 시간의 관계는 다음과 같다.
|
||||||
|
|
||||||
|
- 메모리 크기가 크면,
|
||||||
|
- GC 발생 횟수는 감소한다.
|
||||||
|
- GC 수행 시간은 길어진다.
|
||||||
|
- 메모리 크기가 작으면,
|
||||||
|
- GC 발생 횟수는 짧아진다.
|
||||||
|
- GC 수행 시간은 증가한다.
|
||||||
|
|
||||||
|
| 구분 | 옵션 | 설명 |
|
||||||
|
| ------------- | ------------------ | ------------------------ |
|
||||||
|
| 힙(heap) 영역 크기 | \-Xms | JVM 시작 시 힙 영역 크기 |
|
||||||
|
| 힙(heap) 영역 크기 | \-Xmx | 최대 힙 영역 크기 |
|
||||||
|
| New 영역의 크기 | \-XX:NewRatio | New 영역과 Old 영역의 비율 |
|
||||||
|
| New 영역의 크기 | \-XX:NewSize | New 영역의 크기 |
|
||||||
|
| New 영역의 크기 | \-XX:SurvivorRatio | Eden 영역과 Survivor 영역의 비율 |
|
||||||
|
|
||||||
|
|
||||||
|
> [!note] 이 중에서 중요한 옵션은 -Xms 옵션, -Xmx 옵션, -XX:NewRatio 옵션이다.
|
||||||
|
특히 ==-Xms 옵션과 -Xmx 옵션은 왠만하면 필수로 지정하길 권장==하며, 그리고 NewRatio 옵션을 어떻게 설정하느냐에 따라서 GC 성능에 많은 차이가 발생한다.
|
||||||
|
==NewRatio는 New 영역과 Old 영역의 비율이다.==
|
||||||
|
-XX:+NewRatio=1로 지정하면 (New 영역):(Old 영역)의 비율은 1:1이 된다.
|
||||||
|
만약 1GB라면 (New 영역):(Old 영역)은 500MB:500MB가 된다.
|
||||||
|
NewRatio가 2이면 (New 영역):(Old 영역)이 1:2가 된다.
|
||||||
|
즉, **값이 커지면 커질수록 Old 영역의 크기가 커지고 New 영역의 크기가 작아진다.**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 힙 시작 크기 256mb, 힙 최대 크기 2gb
|
||||||
|
# young 영역과 old 영역 비율 1:2 로 설정 (New 영역:Old 영역 = 1:2)
|
||||||
|
# Parallel GC 로 실행
|
||||||
|
java -Xms256m -Xmx2048m -XX:+NewRatio=2 -XX:+UseParallelGC
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **5.** **튜닝 결과 분석**
|
||||||
|
|
||||||
|
GC 옵션을 지정하고 24시간 이상(하루, 이틀) 데이터를 수집한다.
|
||||||
|
|
||||||
|
그리고 로그를 분석해 메모리가 어떻게 할당되는지 확인한다.
|
||||||
|
|
||||||
|
그 다음에 GC 방식 / 메모리 크기를 변경해 가면서 최적의 옵션을 찾아 나가면 된다.
|
||||||
|
|
||||||
|
분석할 때는 다음의 사항을 중심으로 살펴보는 것이 좋다. 이는 우선 순위 별로 나열되어 있다.
|
||||||
|
|
||||||
|
1. FullGC 수행 시간
|
||||||
|
2. MinorGC 수행 시간
|
||||||
|
3. Full GC 수행 간격
|
||||||
|
4. MinorGC 수행 간격
|
||||||
|
5. 전체 Full GC 수행 시간
|
||||||
|
6. 전체 Minor GC 수행 시간
|
||||||
|
7. 전체 GC 수행 시간
|
||||||
|
8. Full GC 수행 횟수
|
||||||
|
9. Minor GC 수행 횟수
|
||||||
|
|
||||||
|
#### **6.** **전체 서버에 반영 및 종료**
|
||||||
|
|
||||||
|
GC 튜닝 결과가 만족스러우면 전체 서버에 GC 옵션을 적용하고 마무리한다.
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
[[GC]]
|
||||||
|
GC 튜닝이 필요한 이유: [[STW (Stop The World)]]
|
||||||
|
|
||||||
|
- STW가 발생하면 [[GC]]를 실행하는 쓰레드를 제외한 나머지 쓰레드는 모두 작업을 멈춤.
|
||||||
|
- GC작업이 완료된 이후에야 중단했던 작업을 다시 시작됨.
|
||||||
|
- GC가 자주 발생하거나, 또는 시간이 오래 걸리는 경우는 어플리케이션이 비정상 동작하는 시간이 길어진다는 의미이기 때문에 대게의 경우 ==gc 튜닝이란 STW 시간을 줄이는 것을 의미==
|
||||||
|
|
||||||
|
### **GC 튜닝의 주의점**
|
||||||
|
|
||||||
|
그런데 GC 튜닝에 있어서 꼭 명심해야 하는 점이 있다.
|
||||||
|
|
||||||
|
**첫째는, GC 튜닝 옵션은 서비스의 특징 마다 적정 값이 다르다는 것이다.**
|
||||||
|
|
||||||
|
예를 들어 '누가 이 옵션값을 썼을 때 성능이 잘 나왔으니 우리도 이렇게 적용하자.' 라고 생각하면 절대 안 된다.
|
||||||
|
|
||||||
|
왜냐하면 서비스 주제와 특징마다 생성되는 객체의 크기도 다르고 살아있는 기간도 다르기 때문이다.
|
||||||
|
|
||||||
|
따라서 별도의 성능 모니터링을 통해 어느 지점에서 GC의 STW 문제가 나는지 **서비스마다 제각각 파악**하여 GC 튜닝을 진행할 필요가 있다.
|
||||||
|
|
||||||
|
**둘째는, GC 튜닝은 가장 마지막에 하는 작업이라는 것이다.**
|
||||||
|
|
||||||
|
GC 튜닝은 필요한 선행 지식과, 신경써야할 요소, 리스크에 비해서 얻어가는 부분이 너무 적기 때문에, GC를 건드리는 것보다 애플리케이션 코드로써 메모리 최적화를 더 신경 쓸것을 권장하는 의견도 있다.
|
||||||
|
|
||||||
|
GC 튜닝을 왜 하는지 근본적인 이유를 생각해보자.
|
||||||
|
|
||||||
|
일반적으로 Java에서 생성된 객체는 가비지 컬렉터가 처리해서 지운다.
|
||||||
|
|
||||||
|
즉, 생성된 객체가 많으면 많을수록 가비지 컬렉터가 처리해야 하는 대상도 많아지고, GC를 수행하는 횟수도 증가한다는 말이다. 그리고 GC의 수행 횟수가 늘어나면 STW 횟수도 많아지니 성능에 영향이 가게 된다.
|
||||||
|
|
||||||
|
따라서 GC 자체를 튜닝 하기 이전에 먼저 코드 단에서 **쓸모없는 객체 생성을 줄이는 리팩토링 작업을 먼저** 하는 것이 근본적인 해결법이 된다.
|
||||||
|
|
||||||
|
예를들어 ~~String~~ 대신 ~~StringBuilder~~나 ~~StringBuffer~~를 사용하는 거나, 로그를 최대한 적게 쌓도록 하는 등 임시 메모리를 적게 사용하도록 해주는 것이 먼저이다.
|
||||||
|
|
||||||
|
그리고 리팩토링 작업과 어플리케이션 메모리 조정을 해도 여전히 성능에 문제가 생기면 그제서야 GC 튜닝을 진행한다.
|
||||||
|
|
||||||
|
다시 말하자면 GC 튜닝은 자바 어플리케이션 성능 향상 작업에서 가장 마지막에 하는 작업이라는 것을 잊지 말자.
|
||||||
|
|
||||||
|
### **GC 튜닝의 목표**
|
||||||
|
|
||||||
|
**GC 튜닝**이란, 성능상 이슈를 일으키기 쉬운 GC에 대하여 최적화를 진행 하는 것을 말한다.
|
||||||
|
|
||||||
|
GC 튜닝의 목표의 핵심은 [[Minor GC]] 보다 Stop-The-Wold 시간이 긴 [[Major GC]]의 관리이다.
|
||||||
|
|
||||||
|
**첫째는, Old 영역으로 넘어가는 객체의 수 최소화하기 이다.**
|
||||||
|
|
||||||
|
위에서 살펴봤듯이, Old 영역의 크기는 Young(New) 영역의 크기보다 훨씬 거대하다.
|
||||||
|
|
||||||
|
따라서 Old 영역의 GC는 Young(New) 영역의 GC에 비해 상대적으로 시간이 오래 소요되기 때문에, 애초에 Old 영역으로 이동하는 객체의 수를 줄이면 Full GC가 발생하는 빈도를 많이 줄일 수 있게 된다.
|
||||||
|
|
||||||
|
이말은 즉, **Young(New) 영역의 크기를 잘 조절**하여 Old 영역으로 넘어가는 빈도를 줄이면 큰 효과를 볼 수 있다는 뜻이다.
|
||||||
|
|
||||||
|
**둘째는, Full GC 시간 줄이기 이다.**
|
||||||
|
|
||||||
|
Full GC의 실행 시간은 상대적으로 Minor GC에 비해 길기 때문에, Old 영역의 크기를 적절하게 설정하는 것도 하나의 방법이다.
|
||||||
|
|
||||||
|
그렇다고 Old 영역의 크기를 막 줄여버리면 자칫 OutOfMemoryError가 발생하거나 Full GC 횟수가 늘어날 수도 있다.
|
||||||
|
|
||||||
|
반대로 Old 영역의 크기를 늘리면 Full GC 횟수는 줄어들지만 실행 시간이 늘어나게 된다.
|
||||||
|
|
||||||
|
즉, GC 튜닝의 관건은 이 둘 사이를 잘 아우르는 적정 범위를 찾는 것이라 할 수 있다.
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
[[GC]]은 어떤 Object를 Garbage로 판단해서 스스로 지워버릴까?
|
||||||
|
|
||||||
|
가비지 컬렉션은 특정 객체가 garbage인지 아닌지 판단하기 위해서 도달성, 도달능력(Reachability) 이라는 개념을 적용한다.
|
||||||
|
|
||||||
|
객체에 레퍼런스가 있다면 Reachable로 구분되고, 객체에 유효한 레퍼런스가 없다면 Unreachable로 구분해버리고 수거해버린다.
|
||||||
|
|
||||||
|
- Reachable : 객체가 참조되고 있는 상태
|
||||||
|
- Unreachable : 객체가 참조되고 있지 않은 상태 (GC의 대상이 됨)
|
||||||
|
|
||||||
|
![[Heap Unrechable.png]]
|
||||||
|
|
||||||
|
예를들어 JVM 메모리에서는 객체들은 실질적으로 Heap영역에서 생성되고 Method Area이나 Stack Area 에서는 Heap Area에 생성된 객체의 주소만 참조하는 형식으로 구성된다.
|
||||||
|
|
||||||
|
하지만 이렇게 생성된 Heap Area의 객체들이 메서드가 끝나는 등의 특정 이벤트들로 인하여 Heap Area 객체의 메모리 주소를 가지고 있는 참조 변수가 삭제되는 현상이 발생하면, 위의 그림에서의 빨간색 객체와 같이 Heap영역에서 어디서든 참조하고 있지 않은 객체(Unreachable)들이 발생하게 된다.
|
||||||
|
|
||||||
|
이러한 객체들을 주기적으로 가비지 컬렉터가 제거해주는 것이다.
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
### GC (Garbage Collection)
|
||||||
|
|
||||||
|
==사용하지 않는 메모리를 자동으로 회수하여 가용한 공간을 만드는 작업==
|
||||||
|
- GC 전담 thread가 별도로 존재하여 메모리가 부족하다고 판단되는 시점에 주기적으로 일어남
|
||||||
|
- JVM(자바 가상 머신)의 **Heap 영역**에서 **동적으로 할당했던 메모리** 중 **필요 없게 된 메모리 객체(garbage)를 모아 주기적으로 제거**하는 프로세스를 말한다.
|
||||||
|
|
||||||
|
[[GC에 대한 별첨설명]]
|
||||||
|
[[Major GC]] , [[Minor GC]]
|
||||||
|
[[GC 대상]]
|
||||||
|
[[GC Tuning]]
|
||||||
|
[[JVM Heap Area]]
|
||||||
|
[[GC Algorithm]]
|
||||||
|
[[GC Tuning 절차]]
|
||||||
|
|
||||||
|
[[GC Log 수집 방법]]
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
가비지 컬렉션(Garbage Collection, 이하 GC)은 자바의 메모리 관리 방법 중의 하나로 JVM(자바 가상 머신)의 **Heap 영역**에서 **동적으로 할당했던 메모리** 중 **필요 없게 된 메모리 객체(garbage)를 모아 주기적으로 제거**하는 프로세스를 말한다.
|
||||||
|
|
||||||
|
C / C++ 언어에서는 이러한 가비지 컬렉션이 없어 프로그래머가 수동으로 메모리 할당과 해제를 일일이 해줘야 했었다.
|
||||||
|
|
||||||
|
반면 Java에서는 가비지 컬렉터가 메모리 관리를 대행해주기 때문에 Java 프로세스가 한정된 메모리를 효율적으로 사용할수 있게 하고, 개발자 입장에서 메모리 관리, 메모리 누수(Memory Leak) 문제에서 대해 관리하지 않아도 되어 오롯이 **개발에만 집중**할 수 있다는 장점이 있다.
|
||||||
|
|
||||||
|
예시를 들자면 다음과 같은 조금 억지스러운(?) 코드를 실행한다고 가정하자.
|
||||||
|
```java
|
||||||
|
for (int i = 0; i < 10000; i++) {
|
||||||
|
NewObject obj = new NewObject();
|
||||||
|
obj.doSomething();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
루프문에 의해서 10000 건의 NewObject 객체는 for문 스코프 내에서 생성되고 사용되지만, 루프가 끝나고 루프 밖에서는 더이상 사용할 일이 없어진다.
|
||||||
|
|
||||||
|
만일 이런 객체들이 메모리를 계속 점유하고 있다면, 다른 코드를 실행하기 위한 메모리 자원은 지속적으로 줄어들기만 할 것이다. 하지만 우리는 이에 대해서 별다른 작업을 하지 않고 구현 코드를 이어 나간다.
|
||||||
|
|
||||||
|
이것이 가능한 이유는, 가비지 컬렉션(GC)이 한번쓰이고 버려지는 객체들을 주기적으로 비워줌으로써 한정된 메모리를 효율적으로 사용할 수 있게 해주기 때문이다.
|
||||||
|
|
||||||
|
또한 가비지 컬렉션(GC)는 꼭 자바(Java)에만 있는 개념이 아니다.
|
||||||
|
|
||||||
|
파이썬, 자바스크립트, Go 언어 등 **많은 프로그래밍 언어에서 가비지 컬렉션이 기본으로 내장**되어 있다.
|
||||||
|
|
||||||
|
당장 여러분이 보고있는 이 브라우저 역시도 자체적으로 구현된 가비지 컬렉션이 있기 때문에 별다른 메모리 관리 없이 웹페이지를 만들수 있는 것이다.
|
||||||
|
|
||||||
|
따라서 이번 시간에 가비지 컬렉션에 대해 제대로 학습한다면, 자바 외의 언어의 가비지 컬렉션 동작에 대해서도 어느정도 통달되었다고 말할 수 있다.
|
||||||
|
|
||||||
|
그러나 이런 만능 같은 가비지 컬렉션에도 **단점**이 존재한다.
|
||||||
|
|
||||||
|
자동으로 처리해준다 해도 메모리가 언제 해제되는지 정확하게 알 수 없어 제어하기 힘들며, 가비지 컬렉션(GC)이 동작하는 동안에는 다른 동작을 멈추기 때문에 **오버헤드**가 발생되는 문제점이 있다.
|
||||||
|
|
||||||
|
이를 전문적인 용어로 **Stop-The-World** 라 한다.
|
||||||
|
[[STW (Stop The World)]]
|
||||||
|
|
||||||
|
따라서 이 시간을 최소화 시키는 것이 쟁점이다.
|
||||||
|
|
||||||
|
이로 인해 GC가 너무 자주 실행되면 소프트웨어 성능 하락의 문제가 되기도 하다.
|
||||||
|
|
||||||
|
예를들면 익스플로러는 이 가비지 컬렉션를 너무 자주 실행하여 성능 문제를 일으키는 것으로 악명이 높았다.
|
||||||
|
|
||||||
|
이런 특성에 따라 실시간 성이 매우 강조되는 포로그램일 경우 가비지 컬렉터(GC)에게 메모리를 맞기는 것은 맞지 않을 수 있다.
|
||||||
|
|
||||||
|
따라서 어플리케이션의 사용성을 유지하면서 효율적이게 GC를 실행하는 최적화 작업이 개발자의 숙제가 된다.
|
||||||
|
|
||||||
|
그리고 이러한 GC 최적화 작업을 [[GC Tuning]]이라고 한다.
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
### Major GC (Full GC)
|
||||||
|
|
||||||
|
[[Young Generation]]영역에서 살아남은 객체가 이동된 [[Old Generation]]에서 발생하며, Full GC==로 불리기도 함
|
||||||
|
|
||||||
|
Old 영역에서 일어나는 GC로, 기본적으로 [[Mark-Sweep-Compact]] 알고리즘 사용
|
||||||
|
|
||||||
|
- ==Major GC는 작업이 진행되는 동안 어플리케이션 동작이 멈추기== 때문에, 실제 성능 및 안정성에 큰 영향을 미치게 됨
|
||||||
|
|
||||||
|
**Major GC**는 Old 영역이 가득 차면 GC를 실행하는 단순한 방식이다.
|
||||||
|
|
||||||
|
Old 영역에 할당된 메모리가 허용치를 넘게 되면, Old 영역에 있는 모든 객체들을 검사하여 참조되지 않는 객체들을 한꺼번에 삭제하는 Major GC가 실행되게 된다.
|
||||||
|
|
||||||
|
하지만 Old Generation은 Young Generation에 비해 상대적으로 큰 공간을 가지고 있어, 이 공간에서 메모리 상의 ==객체 제거에 많은 시간이 걸리게 된다.==
|
||||||
|
|
||||||
|
예를들어 Young 영역은 일반적으로 Old 영역보다 크키가 작기 때문에 GC가 보통 0.5초에서 1초 사이에 끝난다.
|
||||||
|
|
||||||
|
그렇기 때문에 Minor GC는 애플리케이션에 크게 영향을 주지 않는다.
|
||||||
|
|
||||||
|
하지만 Old 영역의 Major GC는 일반적으로 Minor GC보다 시간이 오래걸리며, 10배 이상의 시간을 사용한다.
|
||||||
|
|
||||||
|
이 때 [[STW (Stop The World)]] 가 문제가 된다.
|
||||||
|
[[Major GC]]가 일어나면 Thread가 멈추고 Mark and Sweep 작업을 해야 해서 CPU에 부하를 주기 때문에 어플리케이션이 멈추거나 버벅이는 현상이 일어나기 때문이다.
|
||||||
|
|
||||||
|
따라서 자바 개발진들은 끊임 없이 **가비지 컬렉션 알고리즘을 발전** 시켜왔다.
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
- Mark
|
||||||
|
Old 영역의 객체 중 사용하는 것과 사용하지 않는 객체 식별
|
||||||
|
- Sweep
|
||||||
|
Heap의 앞 부분부터 사용하지 않는 것으로 식별된 객체 삭제
|
||||||
|
- Compact
|
||||||
|
삭제된 객체가 사용하고 있던 공간을 정리하여 각 객체가 heap의 앞부분부터 연속적으로 쌓이도록 정리
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
새로 생성된 객체가 위치하는 Young 영역에서 발생
|
||||||
|
- Eden([[Young Generation]]) 영역의 GC
|
||||||
|
- Eden 영역 1개와 Survivor 영역 2개를 이용해 Copy & Scavenge 방식으로 GC를 진행
|
||||||
|
|
||||||
|
##### 1st GC
|
||||||
|
- 새로 생성된 대부분의 객체는 Eden 영역에 위치
|
||||||
|
- Eden 영역이 차게 되면 Minor GC가 발생하게 되며 살아남은 객체는 Survivor 영역 중 하나로 이동
|
||||||
|
- 이후 Eden 영역에서 GC가 발생하면 기존에 살아남은 객체가 존재하는 Survivor 영역 쪽으로 계속 쌓임
|
||||||
|
|
||||||
|
##### 2nd GC
|
||||||
|
- 하나의 Survivor 영역이 가득 차게 되면 그 중에 살아남은 객체를 다른 Survivor 영역으로 이동하며, 가득 찼던 Survivor 영역은 데이터가 없는 상태가 됨
|
||||||
|
- 이 과정을 반복하다가 계속해서 살아남아 있는 객체는 Old 영역으로 이동
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
Old Generation은 길게 살아남는 메모리들이 존재하는 공간이다.
|
||||||
|
|
||||||
|
Old Generation의 객체들은 거슬러 올라가면 처음에는 [[Young Generation]]에 의해 시작되었으나, GC 과정 중에 제거되지 않은 경우 age 임계값이 차게되어 이동된 녀석들이다.
|
||||||
|
|
||||||
|
그리고 [[Major GC]]는 객체들이 계속 Promotion되어 Old 영역의 메모리가 부족해지면 발생하게 된다.
|
||||||
|
|
||||||
|
Tip
|
||||||
|
Major GC는 Full GC라고도 불리운다.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
- Java 8의 디폴트 [[GC]]
|
||||||
|
- [[Serial GC]]와 기본적인 알고리즘은 같지만, [[Young Generation]]영역의 [[Minor GC]]를 멀티 쓰레드로 수행 ([[Old Generation]] 영역은 여전히 싱글 쓰레드)
|
||||||
|
- Serial GC에 비해 [[STW (Stop The World)]]시간 감소
|
||||||
|
- Parallel GC의 스레드는 기본적으로 cpu 개수만큼 할당된다.
|
||||||
|
(Single Core에서 Parallel GC로 동작 시 Serial GC로 작동한다.)
|
||||||
|
|
||||||
|
# Parallel Old GC
|
||||||
|
- Parallel GC를 개선한 버전
|
||||||
|
- Young 영역 뿐만 아니라, Old 영역에서도 멀티 쓰레드로 GC 수행
|
||||||
|
- 새로운 가비지 컬렉션 청소 방식인 Mark-Summary-Compact 방식을 이용 (Old 영역도 멀티 쓰레드로 처리)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
- 서버의 CPU 코어가 1개일 때 사용하기 위해 개발된 가장 단순한 [[GC]]
|
||||||
|
- GC를 처리하는 쓰레드가 1개 (싱글 쓰레드) 이어서 가장 [[STW (Stop The World)]] 시간이 길다
|
||||||
|
- [[Minor GC]]에는 Mark-Sweep을 사용하고, [[Major GC]]에는 [[Mark-Sweep-Compact]]를 사용한다.
|
||||||
|
- 보통 실무에서 사용하는 경우는 없다 (디바이스 성능이 안좋아서 CPU 코어가 1개인 경우에만 사용)
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
Young Generation 영역은 짧게 살아남는 메모리들이 존재하는 공간이다.
|
||||||
|
|
||||||
|
모든 객체는 처음에는 Young Generation에 생성되게 된다.
|
||||||
|
|
||||||
|
==Young Generation의 공간은 Old Generation에 비해 상대적으로 작기 때문에 메모리 상의 객체를 찾아 제거하는데 적은 시간이 걸린다. ==(작은 공간에서 데이터를 찾으니까)
|
||||||
|
|
||||||
|
이 때문에 Young Generation 영역에서 발생되는 [[GC]]를 [[Minor GC]]라 한다.
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
## Heap Area
|
||||||
|
힙 메모리(Heap Memory)는 프로그램에서 동적으로 할당된 메모리를 관리하는 데 사용되는 영역입니다. 프로그램이 실행될 때, 운영체제는 프로그램에 메모리 공간을 할당하며, 이 공간은 스택(Stack)과 힙(Heap)으로 구성됩니다. 스택은 지역 변수와 함수 호출 시 생성되는 변수들을 저장하는 영역이고, 힙은 동적으로 할당되는 메모리를 저장하는 영역입니다.
|
||||||
|
|
||||||
|
힙 메모리는 프로그램에서 필요한 만큼의 메모리를 동적으로 할당하여 사용합니다. 이러한 동적 할당은 프로그램에서 사용되는 데이터의 크기를 미리 예측하기 어려울 때 유용합니다. 힙 메모리는 일반적으로 malloc(), calloc(), realloc()과 같은 함수를 사용하여 할당됩니다. 이러한 함수는 메모리의 크기를 결정하고, 메모리 주소를 반환합니다. 반환된 메모리 주소는 포인터 변수에 저장되며, 이 포인터 변수를 통해 할당된 메모리에 접근할 수 있습니다.
|
||||||
|
|
||||||
|
힙 메모리는 스택과 달리, 메모리 블록을 계속해서 할당하거나 해제할 수 있기 때문에, 메모리 누수(Memory Leak)가 발생하기 쉽습니다. 메모리 누수란, 할당된 메모리를 해제하지 않은 채로 프로그램이 종료되거나, 해당 메모리를 더 이상 사용하지 않을 때 발생합니다. 메모리 누수는 시스템의 성능에 영향을 미치며, 심각한 경우 시스템 충돌을 일으킬 수 있습니다. 따라서, 동적으로 할당된 메모리를 사용하는 프로그램에서는 할당된 메모리를 적절한 방법으로 해제하여 메모리 누수를 방지해야 합니다.
|
||||||
|
|
||||||
|
힙 메모리는 운영체제와 프로그램 사이의 중간 영역으로써, 프로그래머가 메모리 관리를 주도적으로 수행할 수 있는 유연성을 제공합니다. 그러나 이러한 유연성은 부적절한 사용으로 인해 메모리 누수와 같은 문제를 발생시킬 수 있으므로, 프로그래머는 힙 메모리를 사용할 때 주의를 기울여야 합니다.
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
**프록시(Proxy)란 '대리', '대신'이라는 뜻을 가지며, 프로토콜에 있어서는 대리 응답 등에서 사용하는 개념**이다.
|
||||||
|
|
||||||
|
==클라이언트와 서버 사이에 존재하며, 중계기로서 대리로 통신을 수행==하는 것을 Proxy라고 하며, 그 중계 기능을 하는 주체를 Proxy Server라고 한다.
|
||||||
|
|
||||||
|
|
||||||
|
##### 프록시 서버의 종류
|
||||||
|
|
||||||
|
###### 포워드 프록시(Forward Proxy)
|
||||||
|
보통 말하는 프록시가 바로 이 포워드 프록시를 말한다.
|
||||||
|
Client와 Server 사이에 위치하여 요청을 중계하며, 요청과 응답은 Proxy Server를 거친다.
|
||||||
|
클라이언트를 감추는 효과가 있다.
|
||||||
|
|
||||||
|
###### 리버스 프록시(Reverse Proxy)
|
||||||
|
포워드 프록시와 마찬가지로 요청과 응답이 Proxy Server로 이동하는데, 포워드 프록시와 다르게 Server들이 주로 내부망으로 구성되며 프록시에게만 연결을 허용한다. 즉, 서비스를 위한 보안 채널을 구축한다.
|
||||||
|
이런 경우 Client가 Server에 직접 접근이 불가능하므로, Reverse Proxy에서 요청을 적극적으로 중계하는 Load Balancing의 역할을 수행하기도 한다.
|
||||||
|
서버를 감추는 효과가 있다.
|
||||||
|
|
||||||
|
##### 프록시 서버를 사용하는 이유
|
||||||
|
|
||||||
|
###### 개인정보를 보호할 수 있다
|
||||||
|
프록시 서버 없이 클라이언트가 서버에 요청 시 본인의 IP 주소가 노출되는데, 프록시 서버를 사용 시 서버측에서 나의 IP가 아닌 프록시 서버의 IP를 보게 된다.
|
||||||
|
즉, IP를 숨길 수 있다.
|
||||||
|
|
||||||
|
###### 캐시를 사용해서 속도가 향상된다
|
||||||
|
프록시 서버는 웹페이지를 가져올 때 자신의 DB에 최근 데이터를 저장하는데, 이것을 Cache라 한다.
|
||||||
|
이렇게 될 시, 같은 요청이 들어오면 Cache자원을 반환하여 서비스의 속도를 높이고 대역폭도 줄일 수 있다.
|
||||||
|
|
||||||
|
###### 로그를 기록, 관리할 수 있다
|
||||||
|
서버 측에선 클라이언트의 기록대신 프록시 서버의 기록이 있지만, 프록시 서버에겐 클라이언트의 기록이 남아있다.
|
||||||
|
이 기록들을 보면 어떤 IP에서 어떤 IP로 얼마나 접속해 있는지 확인할 수 있고, 특정 IP가 방문할 수 있는 웹사이트도 제한할 수 있어서 회사에서 많이 사용한다.
|
||||||
|
|
||||||
|
###### 접속을 우회할 수 있다
|
||||||
|
특정 사이트에서 IP를 검사해 한국에서의 접속을 차단하는 경우가 있는데, 이런 경우 프록시 서버를 사용해 접속 시 다른나라에서 접속한 것처럼 우회할 수 있다.
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
GC를 수행하기 위해 JVM이 프로그램 실행을 멈추는 현상을 의미.
|
||||||
|
GC가 작동하는 동안 GC 관련 Thread를 제외한 모든 Thread는 멈추게 되어 서비스 이용에 차질이 생길 수 있다.
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
### Heap Dump 뜨기
|
||||||
|
```bash
|
||||||
|
jmap -dump:format=b,file=heapdump.hprof {PID}
|
||||||
|
```
|
||||||
|
[[PID]]
|
||||||
|
|
||||||
|
ex)
|
||||||
|
```bash
|
||||||
|
jmap -dump:format=b,file=heapdump.hprof 84544
|
||||||
|
```
|
||||||
|
|
||||||
|
### Heap Dump 분석하기
|
||||||
|
Eclipse Memory Analyzer (MAT)를 사용하자.
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
[https://jplag.github.io/JPlag/](https://jplag.github.io/JPlag/)
|
||||||
|
|
||||||
|
- jdk 17 필요함.
|
||||||
|
- jplag 설치(binary) 필요
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.\java -jar .\jplag-4.2.0-jar-with-dependencies.jar -old C:\MyFolder\temp_workshop\scomorigin -new C:\MyFolder\temp_workshop\scomnow
|
||||||
|
```
|
||||||
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
Process ID
|
||||||
|
|
||||||
|
jps
|
||||||
|
JDK에 포함되어 있는 JPS 명령어를 활용해서 JVM 내부에서 돌아가고 있는 PID를 파악합니다.
|
||||||
|
|
||||||
|
[-v] 옵션을 추가적으로 입력 시 실행 시 입력된 parameter도 확인할 수 있습니다.
|
||||||
|
|
||||||
|
|
||||||
|
Java code로 PID 출력하기
|
||||||
|
```java
|
||||||
|
`System.out.println(``"ProcessID(PID): "` `+ ManagementFactory.getRuntimeMXBean().getName());`
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"_joins":[],"_contexts":[],"_links":[],"_sort":{"field":"rank","asc":false,"group":false,"recursive":false},"_template":"","_templateName":"","defaultSticker":"","readMode":false}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
id: 20250417 MBS의 패키지 구조
|
||||||
|
created: 2025-04-17
|
||||||
|
tags:
|
||||||
|
- 카드
|
||||||
|
---
|
||||||
|
|
||||||
|
# 📌 MBS의 패키지 구조
|
||||||
|
|
||||||
|
## 💡 생각
|
||||||
|
|
||||||
|
MBS는 [[DDD 패키지 구조]] 와 [[NestJS 패키지 구성]]과 [[hi-nest 프로젝트 패키지 구조]] 를 조합해서 만들었음.
|
||||||
|
|
||||||
|
## 🔗 관련 아이디어
|
||||||
|
- [[DDD 패키지 구조]]
|
||||||
|
- [[NestJS 패키지 구성]]
|
||||||
|
- [[hi-nest 프로젝트 패키지 구조]]
|
||||||
|
|
||||||
|
## 🧠 출처 또는 메모
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
## 최종
|
||||||
|
``` plaintext
|
||||||
|
src/
|
||||||
|
└── order/
|
||||||
|
├── domain/
|
||||||
|
│ ├── order.entity.ts ← Order (Aggregate Root)
|
||||||
|
│ ├── order-item.entity.ts ← 내부 엔티티
|
||||||
|
│ ├── value-objects/
|
||||||
|
│ │ └── address.vo.ts ← 값 객체
|
||||||
|
│ └── interfaces/
|
||||||
|
│ └── order.repository.ts ← Repository 인터페이스
|
||||||
|
├── application/
|
||||||
|
│ └── service/
|
||||||
|
│ └── order.service.ts ← 서비스
|
||||||
|
├── presentation/
|
||||||
|
│ ├── dto/
|
||||||
|
│ │ └── create-order.dto.ts ← DTO
|
||||||
|
│ └── controller/
|
||||||
|
│ └── order.controller.ts ← 컨트롤러
|
||||||
|
├── infrastructure/
|
||||||
|
└── order.module.ts ← 모듈
|
||||||
|
```
|
||||||
|
|
||||||
|
![[실제 프로젝트 패키지 구성에 관하여#📌 실제 프로젝트 패키지 구성에 관하여#💡 생각]]
|
||||||
|
|
||||||
|
![[hi-nest 프로젝트 패키지 구조]]
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
설치
|
||||||
|
``` bash
|
||||||
|
npm install -g @nestjs/cli
|
||||||
|
```
|
||||||
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
M(먹) B(비) S(서)
|
||||||
|
먹비서, 영어 약어 아님.
|
||||||
|
굳이 약어를 만들어보자면...
|
||||||
|
|
||||||
|
**M**enu **B**rainy **S**elector라고 우길 수 있겠다.
|
||||||
|
아니, 이거 하면 될듯
|
||||||
|
|
||||||
|
메뉴 추천 어플임
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
``` plaintext
|
||||||
|
src/
|
||||||
|
└── movie/
|
||||||
|
├── dto/
|
||||||
|
│ ├── create-movie.dto.ts
|
||||||
|
│ └── update-movie.dto.ts
|
||||||
|
├── entities/
|
||||||
|
│ └── movie.entity.ts
|
||||||
|
├── movie.controller.ts
|
||||||
|
├── movie.module.ts
|
||||||
|
└── movie.service.ts
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
[ComVisible(true)] : COM Interface에 등록할 수 있도록 보이게 함.
|
||||||
|
(요걸 하면 regasm 명령어로 등록이 가능해짐)
|
||||||
|
``` c#
|
||||||
|
[
|
||||||
|
ComVisible(true),
|
||||||
|
Guid("4f84b96c-d3d9-4b14-ae3a-bbea2bc6a7f8"),
|
||||||
|
ClassInterface(ClassInterfaceType.AutoDispatch),
|
||||||
|
]
|
||||||
|
```
|
||||||
|
위 세가지는 COM에 노출되기위해 반드시 있어야하는 옵션들임.
|
||||||
|
```c#
|
||||||
|
[ComVisible(true)]
|
||||||
|
[ClassInterface(ClassInterfaceType.None)]
|
||||||
|
[ProgId("kr.co.aim.iobridge.secs.service.DriverInstance")]
|
||||||
|
public class DriverInstance
|
||||||
|
{ ... 생략
|
||||||
|
```
|
||||||
|
위의 과정을 거치고 build하면 TLB도 같이 떨어짐.
|
||||||
|
|
||||||
|
Assembly 등록 (COM에 dll 등록)
|
||||||
|
```bash
|
||||||
|
regasm /codebase .\CSLib.dll
|
||||||
|
|
||||||
|
regasm /u /codebase .\CSLib.dll
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
RAD Studio ( 델파이 프로젝트에 TBL 등록 )
|
||||||
|
![[Pasted image 20240206150810.png]]
|
||||||
|
|
||||||
|
|
||||||
|
Chat GPT
|
||||||
|
Q: 프로젝트에 TLB도 추가되어 있어야하고 레지스트리에도 추가가 되어있어야 하는거야?
|
||||||
|
A: COM 객체를 사용하는 Delphi 프로젝트에서는 해당 COM 객체의 Type Library(TLB)를 프로젝트에 추가하고, 레지스트리에도 등록되어 있어야 합니다.
|
||||||
|
|
||||||
|
|
||||||
|
![[Pasted image 20240206150030.png]]
|
||||||
|
![[Pasted image 20240206150106.png]]
|
||||||
|
|
||||||
|
Class를 그대로 쓰기보다는 Interface를 만들어서 쓰는게 조금 더 호환성이 좋은 것 같긴함.
|
||||||
|
|
||||||
|
```c#
|
||||||
|
[
|
||||||
|
ComVisible(true),
|
||||||
|
Guid("c5a0e65b-c891-47f4-9610-297314a6e22a"),
|
||||||
|
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
|
||||||
|
]
|
||||||
|
public interface ICallback
|
||||||
|
{
|
||||||
|
void OnConnection(ConnectionInfo connStatus);
|
||||||
|
void OnMessageReceived(ReceivedInfo receivedInfo);
|
||||||
|
void OnMessageSendFinished(SendFinishInfo sendInfo);
|
||||||
|
void OnDriverEvent(DriverEventInfo driverEvent);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
c#에서 COM 호환가능한 Interface를 만들려면 (혹은 만들어주려면)
|
||||||
|
InterfaceType(ComInterfaceType.InterfaceIsIUnknown) 이 문구가 반드시 필요함.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- **32비트 DLL을 64비트 레지스트리에 등록할 때:**
|
||||||
|
|
||||||
|
- `HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\`
|
||||||
|
- **32비트 DLL을 32비트 레지스트리에 등록할 때:**
|
||||||
|
|
||||||
|
- `HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Classes\Interface\`
|
||||||
|
|
||||||
|
인터페이스는 regasm 이 등록해주지 않는 것 같다.
|
||||||
|
Visual Stuido 에서 COM Interop 등록 체크해놓고 빌드하면
|
||||||
|
이때는 VS가 인터페이스도 등록을 해주는 것 같음.
|
||||||
|
이 때, AnyCPU로 빌드를 하면 인터페이스는 wow6432node의 하위 interface 디렉토리에 추가해준다.
|
||||||
|
x86으로 빌드하면 추가가.. 안되나?;; 아에 추가가 안된다.
|
||||||
|
|
||||||
|
cmd에서 바로 등록하려면 /tlb 옵션넣으면 된다.
|
||||||
|
|
||||||
|
.tlb 파일은 남에게 줘도 아무 의미가 없을 듯 하다.
|
||||||
|
dll 가지고 각자 알아서 tlb를 만들어야 만드는 과정에서 그 환경에 맞는 레지스트리 위치에
|
||||||
|
interface 등록을 하기 떄문이다.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/==Classes==/Interface/{C5A0E65B-C891-47F4-9610-297314A6E22A}
|
||||||
|
|
||||||
|
/HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/Interface/{C5A0E65B-C891-47F4-9610-297314A6E22A}
|
||||||
|
|
||||||
|
두개의 경로가 있는데..? 왜지..?
|
||||||
|
둘 중 하나만 지워도 둘 다 사라짐..;;
|
||||||
|
|
||||||
|
인터페이스는 HKEY_LOCAL_MACHINE 하위에 등록해서 쓰는 거 같고
|
||||||
|
클래스는 HKEY_CLASSES_ROOT 하위에 등록해서 쓰는 것 같다.
|
||||||
|
|
||||||
|
TLB는 32비트, 64비트 와 상관이 없다.
|
||||||
|
dll은 각각 비트의 regasm 명령어로 각각 dll을 추가해줘야한다.
|
||||||
|
( 안해주면 잘못된 클래스 문자열입니다. 에러 발생함 )
|
||||||
|
|
||||||
|
|
||||||
|
c#에서 델파이 함수를 Interface로 호출할 때 stdcall 붙여주는거..
|
||||||
|
안붙이면 x86에서 안됐음
|
||||||
|
|
||||||
|
|
||||||
|
tlb 파일 만들 때 regasm.exe를 x86 버전으로 사용해야함. x64꺼로 사용해서 만든 tlb는
|
||||||
|
rad studio에 등록이 안됨. ( 이유는 모르겠음, successfuly 라고 뜨는데 등록은 안됨. 버그같기도 함 )
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
Heap Dump를 뜨고 분석해서 메모리 누수를 찾았었음
|
||||||
|
|
||||||
|
[[Heap Dump]]
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
for IOBridge_SECS java
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<Configuration>
|
||||||
|
<CustomLevels>
|
||||||
|
<CustomLevel name="RAW_R" intLevel="1001"/>
|
||||||
|
<CustomLevel name="RAW_S" intLevel="1002"/>
|
||||||
|
<CustomLevel name="SECS_R" intLevel="1011"/>
|
||||||
|
<CustomLevel name="SECS" intLevel="1012"/>
|
||||||
|
<CustomLevel name="SECS_S" intLevel="1013"/>
|
||||||
|
<CustomLevel name="SECS_DATA_R" intLevel="1021"/>
|
||||||
|
<CustomLevel name="SECS_DATA" intLevel="1022"/>
|
||||||
|
<CustomLevel name="SECS_DATA_S" intLevel="1023"/>
|
||||||
|
<CustomLevel name="DRIVER" intLevel="1031"/>
|
||||||
|
</CustomLevels>
|
||||||
|
<Properties>
|
||||||
|
|
||||||
|
</Properties>
|
||||||
|
<Appenders>
|
||||||
|
<RollingFile name="raw" immediateFlush="true">
|
||||||
|
<FileName>${ctx:APP_LOG_ROOT}/${ctx:DEVICEID}/RawByte/${ctx:DEVICEID}_RawByte.log</FileName>
|
||||||
|
<FilePattern>${ctx:APP_LOG_ROOT}/${ctx:DEVICEID}/RawByte/${ctx:DAY_PATTERN}/${ctx:FILE_PATTERN}_RawByte_%i.log</FilePattern>
|
||||||
|
<PatternLayout pattern="%d{[HH:mm:ss.SSS]}%m%n"/>
|
||||||
|
<Policies>
|
||||||
|
<!-- size 단위: Byte(default), KB, MB, or GB -->
|
||||||
|
<SizeBasedTriggeringPolicy>
|
||||||
|
<size>${ctx:MAX_FILE_SIZE}</size>
|
||||||
|
</SizeBasedTriggeringPolicy>
|
||||||
|
<!-- interval(default 1)이므로 1초 간격으로 rolling 수행 -->
|
||||||
|
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||||
|
</Policies>
|
||||||
|
<LevelRangeFilter minLevel="RAW_R" maxLevel="RAW_S" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||||
|
<DefaultRolloverStrategy max="999"/>
|
||||||
|
</RollingFile>
|
||||||
|
<Async name="AsyncRawAppender">
|
||||||
|
<AppenderRef ref="raw"/>
|
||||||
|
</Async>
|
||||||
|
|
||||||
|
<RollingFile name="secs" immediateFlush="true">
|
||||||
|
<FileName>${ctx:APP_LOG_ROOT}/${ctx:DEVICEID}/SECS_Header/${ctx:DEVICEID}_SECS_Header.log</FileName>
|
||||||
|
<FilePattern>${ctx:APP_LOG_ROOT}/${ctx:DEVICEID}/SECS_Header/${ctx:DAY_PATTERN}/${ctx:FILE_PATTERN}_SECS_Header_%i.log</FilePattern>
|
||||||
|
<PatternLayout pattern="%d{[HH:mm:ss.SSS]}%m%n"/>
|
||||||
|
<Policies>
|
||||||
|
<!-- size 단위: Byte(default), KB, MB, or GB -->
|
||||||
|
<SizeBasedTriggeringPolicy>
|
||||||
|
<size>${ctx:MAX_FILE_SIZE}</size>
|
||||||
|
</SizeBasedTriggeringPolicy>
|
||||||
|
<!-- interval(default 1)이므로 1초 간격으로 rolling 수행 -->
|
||||||
|
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||||
|
</Policies>
|
||||||
|
<LevelRangeFilter minLevel="SECS_R" maxLevel="SECS_S" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||||
|
<DefaultRolloverStrategy max="999"/>
|
||||||
|
</RollingFile>
|
||||||
|
<Async name="AsyncSECSAppender">
|
||||||
|
<AppenderRef ref="secs"/>
|
||||||
|
</Async>
|
||||||
|
|
||||||
|
<RollingFile name="secsdata" immediateFlush="true">
|
||||||
|
<FileName>${ctx:APP_LOG_ROOT}/${ctx:DEVICEID}/SECS_Data/${ctx:DEVICEID}_SECS_Data.log</FileName>
|
||||||
|
<FilePattern>${ctx:APP_LOG_ROOT}/${ctx:DEVICEID}/SECS_Data/${ctx:DAY_PATTERN}/${ctx:FILE_PATTERN}_SECS_Data_%i.log</FilePattern>
|
||||||
|
<PatternLayout pattern="%d{[HH:mm:ss.SSS]}%m%n"/>
|
||||||
|
<Policies>
|
||||||
|
<!-- size 단위: Byte(default), KB, MB, or GB -->
|
||||||
|
<SizeBasedTriggeringPolicy>
|
||||||
|
<size>${ctx:MAX_FILE_SIZE}</size>
|
||||||
|
</SizeBasedTriggeringPolicy>
|
||||||
|
<!-- interval(default 1)이므로 1초 간격으로 rolling 수행 -->
|
||||||
|
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||||
|
</Policies>
|
||||||
|
<LevelRangeFilter minLevel="SECS_DATA_R" maxLevel="SECS_DATA_S" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||||
|
<DefaultRolloverStrategy max="999"/>
|
||||||
|
</RollingFile>
|
||||||
|
<Async name="AsyncSECSDataAppender">
|
||||||
|
<AppenderRef ref="secsdata"/>
|
||||||
|
</Async>
|
||||||
|
|
||||||
|
<RollingFile name="driver" immediateFlush="true">
|
||||||
|
<FileName>${ctx:APP_LOG_ROOT}/${ctx:DEVICEID}/Driver/${ctx:DEVICEID}_Driver.log</FileName>
|
||||||
|
<FilePattern>${ctx:APP_LOG_ROOT}/${ctx:DEVICEID}/Driver/${ctx:DAY_PATTERN}/${ctx:FILE_PATTERN}_Driver_%i.log</FilePattern>
|
||||||
|
<PatternLayout pattern="%d{[HH:mm:ss.SSS]}[%-5p] - %m%n"/>
|
||||||
|
<Policies>
|
||||||
|
<!-- size 단위: Byte(default), KB, MB, or GB -->
|
||||||
|
<SizeBasedTriggeringPolicy>
|
||||||
|
<size>${ctx:MAX_FILE_SIZE}</size>
|
||||||
|
</SizeBasedTriggeringPolicy>
|
||||||
|
<!-- interval(default 1)이므로 1초 간격으로 rolling 수행 -->
|
||||||
|
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||||
|
</Policies>
|
||||||
|
<!-- <LevelRangeFilter minLevel="ERROR" maxLevel="INFO" onMatch="ACCEPT" onMismatch="DENY"/> -->
|
||||||
|
<DefaultRolloverStrategy max="999"/>
|
||||||
|
</RollingFile>
|
||||||
|
<Async name="AsyncDriverAppender">
|
||||||
|
<AppenderRef ref="driver"/>
|
||||||
|
</Async>
|
||||||
|
</Appenders>
|
||||||
|
<Loggers>
|
||||||
|
<Logger Level="ALL" additivity="false" name="kr.co.aim.iobridge.secs.logger">
|
||||||
|
<AppenderRef ref="AsyncRawAppender"/>
|
||||||
|
<AppenderRef ref="AsyncSECSAppender"/>
|
||||||
|
<AppenderRef ref="AsyncSECSDataAppender"/>
|
||||||
|
<AppenderRef ref="AsyncDriverAppender"/>
|
||||||
|
</Logger>
|
||||||
|
</Loggers>
|
||||||
|
</Configuration>
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
```xml
|
||||||
|
<log4net>
|
||||||
|
<appender name="RAW" type="log4net.Appender.RollingFileAppender">
|
||||||
|
<file value="${ctx:APP_LOG_ROOT}\${ctx:DEVICEID}\Raw\" />
|
||||||
|
<appendToFile value="true" />
|
||||||
|
<maximumFileSize value="10MB" />
|
||||||
|
<rollingStyle value ="Composite" />
|
||||||
|
<maxSizeRollBackups value="999"/>
|
||||||
|
<datePattern value="${ctx:DATE_PATTERN}\\${ctx:FILE_PATTERN}'-RawByte.log'"/>
|
||||||
|
<preserveLogFileNameExtension value="true" />
|
||||||
|
<encoding value="utf-8" />
|
||||||
|
<staticLogFileName value="false" />
|
||||||
|
<layout type="log4net.Layout.PatternLayout">
|
||||||
|
<conversionPattern value="[%d{HH:mm:ss.fff}][%-5p] - %m%n" />
|
||||||
|
</layout>
|
||||||
|
<immediateFlush value="true"/>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="SECS" type="log4net.Appender.RollingFileAppender">
|
||||||
|
<file value="${ctx:APP_LOG_ROOT}\${ctx:DEVICEID}\SECS_Header\" />
|
||||||
|
<appendToFile value="true" />
|
||||||
|
<maximumFileSize value="10MB" />
|
||||||
|
<rollingStyle value ="Composite" />
|
||||||
|
<maxSizeRollBackups value="999"/>
|
||||||
|
<datePattern value="${ctx:DATE_PATTERN}\\${ctx:FILE_PATTERN}'-SECS_Header.log'"/>
|
||||||
|
<preserveLogFileNameExtension value="true" />
|
||||||
|
<encoding value="utf-8" />
|
||||||
|
<staticLogFileName value="false" />
|
||||||
|
<layout type="log4net.Layout.PatternLayout">
|
||||||
|
<conversionPattern value="[%d{HH:mm:ss.fff}][%-5p] - %m%n" />
|
||||||
|
</layout>
|
||||||
|
<immediateFlush value="true"/>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="SECSDATA" type="log4net.Appender.RollingFileAppender">
|
||||||
|
<file value="${ctx:APP_LOG_ROOT}\${ctx:DEVICEID}\SECS_Data\" />
|
||||||
|
<appendToFile value="true" />
|
||||||
|
<maximumFileSize value="10MB" />
|
||||||
|
<rollingStyle value ="Composite" />
|
||||||
|
<maxSizeRollBackups value="999"/>
|
||||||
|
<datePattern value="${ctx:DATE_PATTERN}\\${ctx:FILE_PATTERN}'-SECS_Data.log'"/>
|
||||||
|
<preserveLogFileNameExtension value="true" />
|
||||||
|
<encoding value="utf-8" />
|
||||||
|
<staticLogFileName value="false" />
|
||||||
|
<layout type="log4net.Layout.PatternLayout">
|
||||||
|
<conversionPattern value="[%d{HH:mm:ss.fff}][%-5p] - %m%n" />
|
||||||
|
</layout>
|
||||||
|
<immediateFlush value="true"/>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="DRIVER" type="log4net.Appender.RollingFileAppender">
|
||||||
|
<file value="${ctx:APP_LOG_ROOT}\${ctx:DEVICEID}\Driver\" />
|
||||||
|
<appendToFile value="true" />
|
||||||
|
<maximumFileSize value="10MB" />
|
||||||
|
<rollingStyle value ="Composite" />
|
||||||
|
<maxSizeRollBackups value="999"/>
|
||||||
|
<datePattern value="${ctx:DATE_PATTERN}\\${ctx:FILE_PATTERN}'-Driver.log'"/>
|
||||||
|
<preserveLogFileNameExtension value="true" />
|
||||||
|
<encoding value="utf-8" />
|
||||||
|
<staticLogFileName value="false" />
|
||||||
|
<layout type="log4net.Layout.PatternLayout">
|
||||||
|
<conversionPattern value="[%d{HH:mm:ss.fff}][%-5p] - %m%n" />
|
||||||
|
</layout>
|
||||||
|
<immediateFlush value="true"/>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<logger name="IOBridge_SECS.RAW" additivity="false">
|
||||||
|
<level value="ALL" />
|
||||||
|
<appender-ref ref="RAW" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<logger name="IOBridge_SECS.SECS" additivity="false">
|
||||||
|
<level value="ALL" />
|
||||||
|
<appender-ref ref="SECS" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<logger name="IOBridge_SECS.SECSDATA" additivity="false">
|
||||||
|
<level value="ALL" />
|
||||||
|
<appender-ref ref="SECSDATA" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<logger name="IOBridge_SECS.DRIVER" additivity="false">
|
||||||
|
<level value="ALL" />
|
||||||
|
<appender-ref ref="DRIVER" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
</log4net>
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
![[Pasted image 20240206150416.png]]
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
[[Jplag]] 로 비교함. 최초 99% -> 60%대까지 줄였다가
|
||||||
|
새로 개발하자로 노선이 변경되어 (4월경) 새롭게 개발함
|
||||||
|
|
||||||
|
최종적으로 20%대 후반이 나왔지만 이정도면
|
||||||
|
다른소스나 다를 바 없다고 판단할 수 있을 듯 함.
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
레지스트리 경로에서 불필요한 경로를 지워버리고 엔터때리면
|
||||||
|
알아서 바뀜
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
AMHS (Automated Material Handling Systems: 자동화 물류 반송 시스템)
|
||||||
|
Clean WAY를 통해서 FOUP을 천정반송 하는 OHT (천장에 매달려있는 레일형태의 물류설비)
|
||||||
|
FOUP을 보관하는 역활을 하는 ==STB==, AZFS와 STOCKER
|
||||||
|
FOUP을 층간반송하는 ZIP TOWER로 구성되어 있습니다.
|
||||||
|
(ZIP TOWER는 하이닉스에서 쓰는 단어, 일반적으론 리프터라고 한다고 함.)
|
||||||
|
|
||||||
|
**반송 장비** 라는 말도 AMHS 장비를 의미하는 것 같음.
|
||||||
|
- FAB내에 자재들을 반송 / 운송하는 장비
|
||||||
|
- 사람에 의한 반송이 아닌 자동화 장비들에 의한 반송
|
||||||
|
|
||||||
|
반송장비에 해당되는 설비들
|
||||||
|
- [[Stocker]]
|
||||||
|
- [[OHT]] (Overhead Hoist Transport)
|
||||||
|
- [[OHS]] (Overhead Shuttle)
|
||||||
|
- [[Lifter]]
|
||||||
|
- Conveyor
|
||||||
|
- AGV (Automated Guided Vehicles)
|
||||||
|
- RGV (Rail Guided Vehicles)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
alternate(대체) [[Storage]](저장소)
|
||||||
|
|
||||||
|
- 반송 명령 수행 중 반송 완료가 불가능할 경우 대체 저장소로 저장되어 대기함.
|
||||||
|
- 반송 명령의 최종 목적지를 기준으로 등록 가능
|
||||||
|
( 최종 목적지 직전 저장소에서 갈 수 있는 곳이어야 함 )
|
||||||
|
- 복수개의 Alternate Storage 등록 가능 ( Priority 설정하여 순서 정하기가 가능함 )
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
Bridge Group을 클릭하면 [[Transport Machine]] Management가 뜬다.
|
||||||
|
이는 Bridge가 [[Transport Machine]] 이라는 개념에 포함되는 개념이라서 그렇다.
|
||||||
|
|
||||||
|
Bridge = Convayer = [[InterRail]] Machine 이며
|
||||||
|
이들은 대개 별도의 통신을 하지 않는다. (하는 경우가 아에 없는건 아니라고 함)
|
||||||
|
|
||||||
|
컨베이어벨트를 생각해보자.
|
||||||
|
컨베이어벨트는 작동, 정지 두가지만 잘 되면 된다.
|
||||||
|
그래서 SECS 통신등의 통신수단으로 연결하지 않는다.
|
||||||
|
( 상태보고 같은걸 할 필요가 없으니까 )
|
||||||
|
|
||||||
|
이 설비들은 Ports가 없다.
|
||||||
|
( 컨베이어위에 물건을 올리거나 회수하기만 하면 되니까 port라는게 따로 있을 필요가 없다 )
|
||||||
|
![[Pasted image 20231215161230.png]]
|
||||||
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
크레인, 포크레인팔처럼 로봇팔같은걸 의미한단다..
|
||||||
|
|
||||||
|
보통 [[Stocker]] 내부에 있으며
|
||||||
|
- LP(Load Port)에 있는 물류를 내부의 Shelf로 옮기거나
|
||||||
|
- Shelf에 있는 물류를 OP(Out Port)로 옮겨주는 역할을 한다.
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
| Service | 기 능 | |
|
||||||
|
| ---- | ---- | ---- |
|
||||||
|
| Route Service | § 모든 반송 경로 탐색 (available + unavailable + banned)<br>§ 최적 반송 경로 탐색 | |
|
||||||
|
| | | |
|
||||||
|
| Transfer Service | § 반송 가능한 목적지 결정<br>§ 반송 명령 Queue 및 반송 상태 관리 | |
|
||||||
|
| | | |
|
||||||
|
| Resource Service | § Machine (Storage, Rail, InterStorage, InterRail, Process) 상태 관리<br>§ Unit (Port, Vehicle, Crane, Shelf) 상태 관리 | |
|
||||||
|
| | | |
|
||||||
|
| Material Service | § Carrier 상태 관리<br>§ Carrier 위치 관리 및 탐색 기능 제공 | |
|
||||||
|
| | | |
|
||||||
|
| History Service | § Carrier 별 반송 명령 및 단윈 반송 History 관리<br>§ 장비 별 In / Out History 관리 | |
|
||||||
|
| | | |
|
||||||
|
| Reconcile Service | § Reconcile for Transfer/Carrier<br>§ Reconcile for ActiveZone (only for STKSEM)<br>§ Reconcile for Vehicle (only for IBSEM) | |
|
||||||
|
| | | |
|
||||||
|
| Alarm Service | § Alarm Set/Cleared 처리<br>§ AlarmReport Set/Cleared 처리 | |
|
||||||
|
| | | |
|
||||||
|
| Interface Service | § MES 에 대한 다양한 메시지 SET 제공 (Object, String, xml)<br>§ 다양한 ESB 지원<br>§ AMHS 장비 Interface (STOCKER-SEM, IB-SEM 지원) | |
|
||||||
|
| | | |
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
### Green MCS
|
||||||
|
- 반도체 FPD 공장에 최적화된 자동 반송 시스템 (MCS를 구현한 aim 제품)
|
||||||
|
- 각 설비의 상태와 반송을 담당하는 Framework
|
||||||
|
|
||||||
|
### GreenMCS 특징
|
||||||
|
- MES로 부터 받은 반송 명령에 대한 Route 설정 및 반송 장비 관리
|
||||||
|
( MES와 연동되는 기능 자체도 GreenMCS의 특징인가보다 )
|
||||||
|
- FAB내 상황 변화에 효과적 대처, 효율적인 Dynamic Routing 설정
|
||||||
|
- [[AMHS]] 장비 및 Carrier에 대한 실시간 모니터링
|
||||||
|
( AMHS장비란 OHT, STB, AZFS, Stocker 등의 물류설비들을 모두 통칭함 )
|
||||||
|
- 최적의 반송 경로 탐색 알고리즘
|
||||||
|
- Host & AMHS 인터페이스 제공
|
||||||
|
|
||||||
|
![[Pasted image 20231205131420.png]]
|
||||||
|
|
||||||
|
- **T**rans **S**erver (TS)
|
||||||
|
( 자재, 반송, 경로 등 모든 물류 자재의 반송 관련 기능 수행 )
|
||||||
|
- **E**quipment **I**nterface **S**erver (EI, ES)
|
||||||
|
( AMHS Interface, SECS Message <-> XML Doc 맵핑 및 파싱, 전송 )
|
||||||
|
**C**ontrol **S**erver (CS)
|
||||||
|
( MCS App들에 Heartbeat 체크, Service & Workflow reload, App Control, AMHS Control )
|
||||||
|
- **D**aemon **S**erver (DS)
|
||||||
|
( async 하게 작동해야 하는 동작들을 수행함. awake alternated transport job, garbage data delete, log backup 등 )
|
||||||
|
|
||||||
|
- MES Interface
|
||||||
|
- Database
|
||||||
|
- UI (Client)
|
||||||
|
|
||||||
|
![[Pasted image 20231205132711.png]]
|
||||||
|
![[Pasted image 20231205133918.png]]
|
||||||
|
![[Pasted image 20231205133940.png]]
|
||||||
|
![[Pasted image 20231205133951.png]]
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
[[InterStorage]], InterRail 처럼 종류에 Inter가 들어가는 설비들의 경우
|
||||||
|
'SECS 통신을 별도로 할 필요가 없고 [[AMHS]]설비간의 물류 반송을 지원하는 설비' 라고 요약할 수 있음.
|
||||||
|
|
||||||
|
대표적인 InterRail 설비로는 Convayer가 있으며,
|
||||||
|
물류가 어디서 어디로 가는지 그런거 전혀 알 필요 없이 그저 컨베이어 벨트를 돌리기만 하면 되는 설비를 통칭한다고 생각하면 됨.
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
InterStorage, [[InterRail]] 처럼 종류에 Inter가 들어가는 설비들의 경우
|
||||||
|
'SECS 통신을 별도로 할 필요가 없고 [[AMHS]]설비간의 물류 반송을 지원하는 설비' 라고 요약할 수 있음.
|
||||||
|
|
||||||
|
InterStorage설비는 스스로 별도의 통신을 하지 않고 단순반복 작업을 진행하며 별도의 Shelf 저장공간을 가지지 않는 설비를 의미함.
|
||||||
|
|
||||||
|
다만, Interstorage설비의 대표격인 Lifter의 경우 Interstorage설비로 구분을 하긴 하지만
|
||||||
|
엄밀히 말하자면 Lifter가 SECS통신을 하지 않는 것은 아니기 때문에 잘못된 구분처럼 보여진다고 함.
|
||||||
|
( 아마 층간반송을 통해 Storage와 Storage사이에서 물류를 반송해주는 특성 때문에
|
||||||
|
Interstorage로 구분한 것 같음 )
|
||||||
|
|
||||||
|
구분을 잘못해서 그런 것인진 몰라도
|
||||||
|
Interstorage라는 용어 자체를 잘 쓰지 않는 추세라고 함.
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
[[AMHS]]설비의 한 종류이며
|
||||||
|
수평적인 물류 반송이 아닌 수직적인 물류반송을 담당하는 반송설비이다.
|
||||||
|
|
||||||
|
엘리베이터? 같은 느낌이라고 하며
|
||||||
|
층간반송을 담당하는 반송설비이다.
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
**M**aterial **C**ontrol **S**ystem
|
||||||
|
- 물류 제어(반송[^물건 따위를 운반하여 보냄.] ) 시스템
|
||||||
|
|
||||||
|
Trans Server (TS)의 역할을 보면 아래 두가지가 있고
|
||||||
|
- MES로 부터 요청 받은 XML Message에 관한 반송 생성 및 반송 로직 수행
|
||||||
|
- 반송 명령과 Carrier에 관한 모든 이벤트는 MES로 보고
|
||||||
|
|
||||||
|
nanoTrans (Green MCS)의 특징에 보면 이런내용이 있는걸로 봐서
|
||||||
|
- MES로 부터 받은 반송 명령에 대한 Route 설정 및 반송 장비 관리
|
||||||
|
- 최적의 반송 경로 탐색 알고리즘
|
||||||
|
|
||||||
|
MCS의 가장 중요한 기능중 하나로
|
||||||
|
#### MES가 알려준 물류의 최종 목적지로 실질적으로 반송을 한다.
|
||||||
|
가 될 수 있겠다.
|
||||||
|
|
||||||
|
목적지로 물류를 반송하기 위해서는 목적지까지의 경로를 알아야 하고
|
||||||
|
경로내에 있는 AMHS설비들에게 명령을 내릴 수 있어야 한다.
|
||||||
|
그래서 두번째 MCS의 기능으로
|
||||||
|
#### AMHS설비들에 실질적인 명령을 내릴 수 있어야 한다.
|
||||||
|
가 있겠다.
|
||||||
|
|
||||||
|
이 두가지 주요 업무를 수행하기 위해서 AMHS 장비 관리 및 인터페이스가 가능해야하고
|
||||||
|
기준정보 관리 및 상태정보 관리를 위해 DB가 필요하다.
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
※ nanoTrans 및 Green MCS 기준이 아님
|
||||||
|
|
||||||
|
![[MCS Architecture.png]]
|
||||||
|
-> 대략 이런 느낌의 것을 구현해내면 MCS System을 구현했다고 할 수 있지 않을까 싶음.
|
||||||
|
이걸 구현해낸 aim사 제품이 nanoTrans (greenMCS) 인거고..
|
||||||
|
**( 이 기능이 MCS의 전부는 절대 아니고 일부분일 것임. )**
|
||||||
|
|
||||||
|
nanoTrans Functionality 문서를 보면 16가지의 기능이 정의되어 있는데
|
||||||
|
- Dynamic Route -> 물류 반송 중간중간마다 동적으로 최적경로를 재탐색 하겠다. (**물류 반송**)
|
||||||
|
- Fixed Route -> 사용자가 정의한 고정된 경로로만 반송하겠다. (**물류 반송**)
|
||||||
|
- Load Balancing -> AMHS설비에 과부하 걸리지 않게 밸런싱 하겠다. (**물류 반송**)
|
||||||
|
- Alternate Storage -> 반송명령 수행불가 시 어떻게 처리할것인가? (**물류 반송**, 예외 처리)
|
||||||
|
- Recovery desination -> Idle Carrier의 반송 경로 Block 방지기능 (**물류 반송**)
|
||||||
|
- Fore Transfer -> 반송명령 수행 불가 시 예외처리 (**물류 반송**, 예외 처리)
|
||||||
|
- Carrier Process Type -> Carrier에 따라 반송 (불)가능한 AMHS 설비를 설정하겠다. **물류 반송**)
|
||||||
|
- Bi-Directional Node -> InOut port 강제 제어, 다양한 장비 Scenario 대응 (**물류 반송**, 예외처리)
|
||||||
|
- Transfer Option -> 반송 옵션, 여러가지 예외상황 대응 가능 (**물류 반송**, 예외처리)
|
||||||
|
- Change Destination -> 진행중인 반송명령의 최종 목적지 변경 (**물류 반송**, 예외처리)
|
||||||
|
- Predictive Transfer -> 반송시간 단축을 위한 옵셔널 기능 (**물류 반송**)
|
||||||
|
- Alarm Management -> 알람 발생 및 알람 확인 기능
|
||||||
|
- Storage Full-rate Management -> Storage 장비의 Carrier 저장량 조절 기능
|
||||||
|
- Log Analyzing -> TransServer의 Log를 저장
|
||||||
|
- Rich History -> MCS 명령 수행 이력 관리
|
||||||
|
- High Performance -> 뭔지 잘 모르겠음
|
||||||
|
|
||||||
|
16가지 중 11가지가 물류 반송에 관련된 기능임.
|
||||||
|
물류 반송 기능이 MCS의 핵심 기능이라고 봐도 되는 것 같고
|
||||||
|
물류 반송 기능을 제공하기 위한 서브기능들 몇가지가 추가된 상태로 분석된다.
|
||||||
|
|
||||||
|
즉, 위에 그려놓은 반송 관련 기능이 MCS의 거의 전부라고 봐도 될 듯하다.
|
||||||
|
약어도 보면 Material Control System, 물류 제어 시스템이다.
|
||||||
|
|
||||||
|
자동으로 최적의 경로를 구해서 효율적인 Load Balancing을 하면서
|
||||||
|
어지간한 예외상황에 대해서도 대처가 가능한 물류 반송 자동화 시스템
|
||||||
|
( 물론 사용자를 위한 추가기능도 추가해놓은 )
|
||||||
|
이라고 하면 되겠다.
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
![[2023-11-15 MCS 교육 필기]]
|
||||||
|
|
||||||
|
![[Pasted image 20231215134055.png]] TM18 (Factory)
|
||||||
|
└ ![[Pasted image 20231215134110.png]] ARRAY (Area)
|
||||||
|
└ ![[Pasted image 20231215134125.png]] Array2f (Shop) (Shop과 이름이 Array2f로 같은거임.)
|
||||||
|
└ ![[Pasted image 20231215134135.png]] Array2f (Bay)
|
||||||
|
├ ![[Pasted image 20231215134204.png]] BRIDGE (보통 Convayer를 의미한다함.)
|
||||||
|
├ ![[Pasted image 20231215134208.png]] OHS
|
||||||
|
├ ![[Pasted image 20231215134218.png]] PROCESS
|
||||||
|
└ ![[Pasted image 20231215134228.png]] STOCKER
|
||||||
|
|
||||||
|
Level 구분은 Factory -> Area -> Shop -> Bay 까지 있고
|
||||||
|
그 아래에 있는 BRIDGE, OHS, PROCESS, STOCKER는 각 설비들을
|
||||||
|
타입별로 grouping 해 놓은 것이라고 생각하면 된다.
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
OverHead Shuttle[[24.01.04#^shuttle]]
|
||||||
|
|
||||||
|
Overhead Shuttle
|
||||||
|
머리위에서 특정지점을 빠르게 오고가는 시스템
|
||||||
|
|
||||||
|
Rail을 따라서 물류를 반송하는 반송설비.
|
||||||
|
|
||||||
|
물류를 Rail위에 올리고 반송하기 때문에 무거운 물류 운송에 [[OHT]]보다 유리하다.
|
||||||
|
|
||||||
|
[[Transport Machine]]이자 [[Rail Machine]]에 포함된다.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
Overhead Hoist Transport
|
||||||
|
|
||||||
|
Overhead Hoist Transport
|
||||||
|
머리위에서 들어(끌어)올리는 반송
|
||||||
|
|
||||||
|
머리위에 있으며 인형뽑기 집게같은걸로 들어올리거나 내려주는 식으로
|
||||||
|
물류를 반송하는 반송설비.
|
||||||
|
|
||||||
|
물류가 집게에 잡혀서 매달려있는 형태여서 매우 무거운 물류는 옮기기 힘들다.
|
||||||
|
|
||||||
|
[[Transport Machine]]이자 [[Rail Machine]]에 포함된다.
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
일반적인 MCS에서 사용되는 용어는 아니라고 함.
|
||||||
|
|
||||||
|
TM18에서만 사용하는 특별한 설비종류일수도 있고,
|
||||||
|
|
||||||
|
아무튼 뭔지 모르겠다는 답변을 받음.
|
||||||
|
(Storage로 분류되어 있는걸로 봐선 Stocker Machine의 일종이지 않을까?)
|
||||||
|
|
||||||
|
이름을 잘못지은 것 같다.
|
||||||
|
O(ver)H(ead) 어쩌구저쩌구는 뭔가 RailMachine의 일종처럼 들리니까..
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
MCS에서 Process는 ==생산설비== (AMHS 설비를 제외한, 실제 가동되면서 product를 생산하는)를 의미
|
||||||
|
product는 반드시 완제품이 아니고 여러가지 형태일 수 있다.
|
||||||
|
|
||||||
|
MCS에서 Process는 Equipment라고 보면 되나보다..
|
||||||
|
(Machine 기준정보에 Process - Equipment 라고 되어있음.)
|
||||||
|
|
||||||
|
설비가 process를 완료하기전과 완료후가 외형상 변화가 없는 경우도 있고
|
||||||
|
( 계측설비 같은것들 )
|
||||||
|
그냥 씻기만 하고 내보내는 경우도 있다. ( WET 설비 같은것들 )
|
||||||
|
process 완료 전,후가 엄청 큰 차이를 보이는 경우도 당연히 있고..
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
OHS를 누르면 Rail Machine Management 메뉴가 열림.
|
||||||
|
|
||||||
|
OHS, OHT는 Transport Machine에 포함되긴 하지만
|
||||||
|
Rail Machine이 조금 더 좁은 범위의 분류이기 떄문에
|
||||||
|
Transport Machine Management대신 Rail Machine Management가 열리는 것 같다.
|
||||||
|
|
||||||
|
Rail (선로)이 있고 이 Rail을 통해 물류를 반송하는 설비들을 Rail Machine이라 하는 것 같다.
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
Side Track Buffer
|
||||||
|
|
||||||
|
하이닉스에서만 사용하는 반송설비의 종류
|
||||||
|
|
||||||
|
[[Stocker]] (STK) 와 비슷하게 동작하는 Storage Machine의 일종이고
|
||||||
|
STK와 다르게 설비 내부에 Crane이 없고 OHT가 직접 반송을 해줌.
|
||||||
|
|
||||||
|
OHT 반송 설비의 레일(트랙) 옆에 위치하는..
|
||||||
|
느낌은 Shelf인데(저장소인데),
|
||||||
|
Foup에 질소를 충전하는 곳? 으로 사용되는 것 같습니다.
|
||||||
|
|
||||||
|
찾아보니, UTB (Under Track Buffer) 라는 용어도 있습니다
|
||||||
|
|
||||||
|
트랙 옆에 저장(보관)하면 Side STB
|
||||||
|
트랙 아래에 저장(보관하면 Under) UTB ??
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
( Shelf(선반), Zone ) -> 사실 Shelf랑 [[Zone]]이라고 괄호쳐놓은 이유를 잘 모르겠음
|
||||||
|
|
||||||
|
- Stocker 자체 저장 공간 (선반), Carrier를 보관하는 장소
|
||||||
|
-> 이건 아마 Shelf 라는 단어의 의미인 것 같음.
|
||||||
|
- Crane에 의해 Carrier를 이동, 저장
|
||||||
|
|
||||||
|
==Carrier를 저장해놓거나 Carrier를 필요로하는 생산 설비나 다른 AMHS 설비들에게 넘겨주는 역할을 함==
|
||||||
|
-> Stocker에는 1개 이상의 Crane이 있고 이 Crane이 Input / Output port들로 Carrier를 옮겨줌.
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
storage, 저장 공간
|
||||||
|
|
||||||
|
Storage = [[Stocker]] / STB(ZFS, INVENTORY, UTS, AZFS)
|
||||||
|
내부에 foup을 저장할 수 있는 설비들을 통칭하는 듯 함.
|
||||||
|
|
||||||
|
ZFS, INVENTORY, UTS와 AZFS는 [[STB]]의 한 종류일 가능성이 높음.
|
||||||
|
(STB가 하는 일을 하는건 맞는데 다르게 처리하거나 하는 식)
|
||||||
|
아마 STB처럼 OHT에 의해 Foup을 적재하는 식으로 동작하는 녀석들을 말하는 것 같음
|
||||||
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
[[Transport Job]]이 택배 송장이라면
|
||||||
|
Transport command는 택배의 상세 배송 이력이라고 보면 되겠음.
|
||||||
|
|
||||||
|
현재 진행중인 Trnasport command는 당연히 하나만 존재할 수 있는것이고
|
||||||
|
지금 현재 이 물류가 지금 당장 어떻게 반송되어야 하는지에 대한 정보를 가짐.
|
||||||
|
|
||||||
|
아래 이미지에서 하나하나의 상세 이력.. 저런 느낌인듯
|
||||||
|
지금 이 foup이 A1STK0100 의 Shelf에서 OP로 이동해야한다.
|
||||||
|
이런 상세내역 자체를 의미.
|
||||||
|
|
||||||
|
==Transport command는 Transport Job이 있어야만 존재할 수 있다.==
|
||||||
|
|
||||||
|
![[Pasted image 20240131113033.png]]
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
Carrier에 내려진 반송명령 그 자체를 의미함.
|
||||||
|
택배의 송장과 비슷하다고 보면 될 듯 합니다.
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
출발지: A1STK0100
|
||||||
|
목적지: A1STK2500
|
||||||
|
///////////////////////
|
||||||
|
|
||||||
|
어디에서 어디로 가야한다. 그 자체를 의미하며
|
||||||
|
목적지까지 어떻게 가는지에 대한 상세반송은 [[Transport Command]]를 확인해야 함.
|
||||||
|
|
||||||
|
Carrier 하나당 하나의 TransportJob만 존재할 수 있음.
|
||||||
|
|
||||||
|
MCS는 Lot 단위까지 물류를 관리하지 않지만
|
||||||
|
MES가 알려준 Lot ID에 대해서는 정보를 가지고 있기는 함.
|
||||||
|
그래서 Transport Job History 검색할 때 lot ID로도 검색이 가능한 것 같음.
|
||||||
|
근데 그럼 Transport Command도 lot ID 단위로 검색 가능해야 한 것 아닌가..?
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
MCS에서 Equipment의 종류를 나누는 대분류중 하나.
|
||||||
|
크게 두가지로 분류된다.
|
||||||
|
|
||||||
|
Process Machine , Transport Machine
|
||||||
|
|
||||||
|
Transport Machine은 반송과 관련된 설비 모두를 의미한다.
|
||||||
|
|
||||||
|
Transport Machine
|
||||||
|
├ [[Rail Machine]]
|
||||||
|
└ [[Stocker]] Machine ( Storage )
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
Port / Shelf ( = STBPort) / Crane / Vehicle / Shuttle
|
||||||
|
|
||||||
|
Equipment, AMHS 설비들에 포함되는 모듈들 중
|
||||||
|
따로 관리포인트가 필요한 것들을 통칭하는 용어
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
일종의 Grouping 단위이며 zone에는 여러가지 것들이 포함될 수 있다.
|
||||||
|
( Storage Machine이 될 수도, 그 Machine의 특정 Unit이 될 수도 있고 여러개일 수 있다. )
|
||||||
|
|
||||||
|
사용자가 특정한 조건으로 묶은 개체들에 대해서 동시에 어떠한 설정을 하고자 할 때 쓴다.
|
||||||
|
|
||||||
|
예를들면
|
||||||
|
설비의 port 여러개를 하나의 zone단위로 묶고 이 zone을 특정 설비의 Alternate Storage로
|
||||||
|
지정할 수 있다.
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
sys랑 system은 oracle DB에서 관리자 계정을 의미
|
||||||
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
cmd -> sqlplus -> 계정명 입력에 'sys as sysdba' 입력 -> password 없이 엔터
|
||||||
|
|
||||||
|
SQL > 로 커맨드라인이 약간 바뀜
|
||||||
|
|
||||||
|
show user // 현재 접속한 유저 확인 명령어
|
||||||
|
USER is "SYS" 라고 나오면 성공
|
||||||
|
|
||||||
|
alter user sys identified by 1234; // sys 계정 암호를 1234로 변경
|
||||||
|
User alterd. // 변경 완료
|
||||||
|
|
||||||
|
conn sys/1234 as sysdba; //변경한 암호로 접속 시도
|
||||||
|
Connected. // 접속 완료
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
[Listen]
|
||||||
|
tibrvlisten 서비스명 데몬명 네트워크명 서브젝트명
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tibrvlisten -service "8200" -daemon "tcp:10.20.9.114:7500" -network ";225.11.11.2" PJS.P2.MES.DEV.OLED.PEMsvr
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
[Send]
|
||||||
|
tibrvsend 서비스명 데몬명 네트워크명 서브젝트명 할말
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tibrvsend -service "8200" -daemon "tcp:10.20.9.114:7500" -network ";225.11.11.2" PJS.EDO.MES.DEV.OLED.PEMsvr test
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
Server
|
||||||
|
|
||||||
|
config -> TRANS4 -> startup -> database.properties
|
||||||
|
interface.properties ( environment, server.domain.(mcs).host 개인꺼로 바꿔주기 )
|
||||||
|
( 위 두 파일 설정만 맞춰주면 됨 )
|
||||||
|
|
||||||
|
UI
|
||||||
|
TM18_Client -> plugins -> config.TM18 -> ui.properties
|
||||||
|
|
||||||
|
|
||||||
|
UI_Listener -> MCS 입장에서의 Client들이 보내는 TIB 메시지를 받음
|
||||||
|
Host_Listener -> '' Host가 보내는 TIB 메시지를 받음
|
||||||
|
|
||||||
|
|
||||||
|
MCS에서 JOB은 출발지, 최종목적지에 대한 정보를 의미
|
||||||
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
IB: OHT OHS 등
|
||||||
|
|
||||||
|
SEM?
|
||||||
|
Stocker SEM 이러면 뭔가 Stocker 동작 규약? 그런 뜻인가 봄
|
||||||
|
|
||||||
|
TSC??
|
||||||
|
Transfer SC
|
||||||
|
|
||||||
|
SC? System Control? <---> Semi Conductor?
|
||||||
|
|
||||||
|
OP: Stocker Crane이 닿을 수 있는 최종 ==Out Port==
|
||||||
|
LP: OHT, OHS에 붙어있는 Port ==Loading Port==
|
||||||
|
|
||||||
|
OP <-> LP는 알아서 움직일 수 있다.
|
||||||
|
|
||||||
|
EAP가 반도체설비 대신 물류관련(IB, SC) 설비를 관리하고,
|
||||||
|
반송관련 Order를 내릴 수 있어야 하기 때문에 별도의 DB를 가진다고 생각하면 될 것 같음.
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
Area
|
||||||
|
└
|
||||||
|
FACTORY -> AREA -> <U>SHOP</U> -> BAY
|
||||||
|
(Hynix) 잘안씀 많이씀
|
||||||
|
|
||||||
|
INTERSTORAGE 에서 SHELF를 뺀 것 (LIFTER)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
MCS가 TIB으로 누구랑 연결되어 있는지 확인 필요 (이전 교육내용중에 있었음, 교육자료 보면 될듯)
|
||||||
|
|
||||||
|
AbstractMessage
|
||||||
|
└TransferMessage
|
||||||
|
└ TransportMessage
|
||||||
|
둘 다 반송관련 메시지임. 개별 스토커내부의 반송명령에는 TransportMessage를 쓴다.
|
||||||
|
모든 반송명령 메시지는 TransferMessage (혹은 그 자식 클래스)로 처리한다.
|
||||||
|
이 둘의 구분은 명확하지 않다. 이부분에 대해서는 명확하게 확정해주는게 필요하다.
|
||||||
|
|
||||||
|
Heuristic Delay는 별도의 Daemon Server를 통해 주기적으로 계산한다.
|
||||||
|
(하지만 이 기능 자체를 잘 안쓴다고 함)
|
||||||
|
|
||||||
|
alternate, recovery 두가지의 대체반송이 있음
|
||||||
|
alternate는 job이 있고 recovery는 별도의 job이 없다
|
||||||
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
SEM 문서를 기반으로 개발진행
|
||||||
|
SEMI SPEC 문서랑 굉장히 비슷해보임
|
||||||
|
|
||||||
|
MCS가 close connection 하는것과
|
||||||
|
UI에서 offline 처리하는 것은 다르다. (S1F15)
|
||||||
|
|
||||||
|
Carrier cancel은 동작중일때는 캔슬불가
|
||||||
|
(Cancel은 취소, Abort는 중단)
|
||||||
|
|
||||||
|
차세대MCS에서는
|
||||||
|
Client <-> MCS WebServer 이렇게만 통신하게 할 예정
|
||||||
|
이 둘은 HTTP를 쓸거같고 MCS WebServer가 TS든 CS든 얘네들하고 TIB통신을 할듯함
|
||||||
|
|
||||||
|
기존 MCS에서는
|
||||||
|
UI(Client) <-> TS, CS 두곳과 TIB통신으로 직접 통신했었음.
|
||||||
|
|
||||||
|
기존 UI는 메인 화면 띄울때 버벅이는게 있었고
|
||||||
|
설비수가 천대를 넘어가는 큰 사이트의 경우에는
|
||||||
|
처음 화면 띄울때 켜놓고 나갔다와야할 정도라고..
|
||||||
|
한번띄워놓으면 그다음부터는 좀 낫다고..
|
||||||
|
|
||||||
|
Crane이 out of service되면 Crane이 접근가능한 port들도 같이 out of service가 된다.
|
||||||
|
(Crane이 없으면 해당 port들에 접근할 방법이 없으므로)
|
||||||
|
Crane이 in service가 되면 port들도 같이 in service가 된다.
|
||||||
|
|
||||||
|
(Machine)AlarmSet
|
||||||
|
UnitAlarmSet
|
||||||
|
AlarmCleared 순서로? 세트로 발생된다함
|
||||||
|
|
||||||
|
Machine Alarm, Unit Alarm이 각각 의미하는 바가 있나봄
|
||||||
|
Machine은 설비 그자체,
|
||||||
|
Unit은 Machine에 포함된 Port같은 유닛들을 의미
|
||||||
|
|
||||||
|
Rail OHT는 (일반적으로)Port가 없고
|
||||||
|
Interail은 있다. ?
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
컨플, 지라 확인 (메일 보낸거중에 있음)
|
||||||
|
|
||||||
|
RCP 걷어내는건가?
|
||||||
|
-> ㅇㅇ
|
||||||
|
|
||||||
|
WBS문서 보는방법을 확인하자
|
||||||
|
-> 해야할 일을 정의하고 일정을 어느정도 산정해봄
|
||||||
|
WBS기준으로 JIRA 작성됨
|
||||||
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
Front 화면 설계
|
||||||
|
오븐써서 그린다는 거 같음.
|
||||||
|
|
||||||
|
설계의 범위가 어느정도까지여야 하는가?
|
||||||
|
![[2023-12-14 Client 회의]]
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
WEB UI 설계 - WEB UI 화면 설계
|
||||||
|
|
||||||
|
'이력 조회' '사용자 관리' 'Application 관리' 'Data 조회' '기준 정보 관리 - 모델링' 화면 설계하면 됨.
|
||||||
|
|
||||||
|
화면 설계?
|
||||||
|
: 카카오 오븐으로 프로토타입 제작
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
1. 프로젝트 신규투입인원 오리엔테이션
|
||||||
|
2. 프로젝트 관련 질답 ( 컨플에 자유롭게 게시글작성해도 됨, )
|
||||||
|
3. ==2024.01.11 목요일날 WFB, WFL 관련 교육받아야 함.==
|
||||||
|
4. WBS Gant-Chart에 상위분류에 담당자는 하위분류에 있는 업무들을 관리해야함.
|
||||||
|
5. 화면 개발 관련 정기 회의 : 매주 화,목 오전 10시 30분. 회의실은 예약하는데로 공유
|
||||||
|
|
||||||
|
Backend: 성능개선, IOBridge_SECS 사용으로 변경
|
||||||
|
Frontend: Web으로 변경, UX 개선 (기존과 차이가 많이 나면 안됨)
|
||||||
|
|
||||||
|
**기존에 UI app을 Web버전으로 변경한 적이 있었는데
|
||||||
|
(너무 많이 변해버린 UI/UX로 인해) 못쓰겠다고 해서 다 걷어낸 이력이 있다고 함.
|
||||||
|
지금 쓰고있는 .NET버전의 UI대비 많이 변하면 안됨**
|
||||||
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
aim의 DB설계컨셉
|
||||||
|
1. 기준정보 테이블 따로, 현재 데이터 따로
|
||||||
|
2. ?
|
||||||
|
|
||||||
|
key join
|
||||||
|
|
||||||
|
NXMCS의 DB Table Hierachy
|
||||||
|
FACTORY
|
||||||
|
AREA (SHOP이랑 BAY는 어디로??)
|
||||||
|
EQUIPMENT
|
||||||
|
Unit
|
||||||
|
Port
|
||||||
|
Shelf
|
||||||
|
|
||||||
|
ProhibitTransport: 현재 위치 기준, 반송 불필요 Bay 연결 정보
|
||||||
|
|
||||||
|
Transport Command : 실제 설비로 내려지는 반송명령 그 자체를 의미
|
||||||
|
Transport Job은 무엇?
|
||||||
|
|
||||||
|
Transfer -> Transport 용어 변경,통일
|
||||||
|
|
||||||
|
InterNode != IntraNode, 개념설명 x
|
||||||
|
Inter와 Intra 단어 뜻 그대로 사용되는 개념인가봄
|
||||||
|
|
||||||
|
MCS에서의 Node는 Equipment 이하의 개념들을 의미하는가?
|
||||||
|
( Equipment, Unit, Port, Shelf )
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
기준 정보 관리 - 모델링 start , end date 다시 할당하기
|
||||||
|
|
||||||
|
업무들에 할 일 형태로 설명에 있는 업무들 추가해주기
|
||||||
|
|
||||||
|
2월9일까지 할당량 다 할 수 있는 일정으로 업데이트
|
||||||
|
|
||||||
|
|
||||||
|
반송설비
|
||||||
|
-> 저장 + 반송
|
||||||
|
-> only 반송
|
||||||
|
|
||||||
|
두가지로 나뉨.
|
||||||
|
|
||||||
|
machine -> equipment 로 용어 통일
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
????
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
6월까지 (6월30일) 개발 완료
|
||||||
|
|
||||||
|
FrontEnd는 일단 4월까지 (아마 3월31일까지 인듯) 해보고
|
||||||
|
안되면 김동균선임 추가 투입
|
||||||
|
|
||||||
|
2월5일~8일 화면 설계 Review
|
||||||
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
1. 디자인 시안 리뷰 (제안)
|
||||||
|
- micro-copy = 좋아요 ? 좋아요 기능을 이야기하는 것 같음. UX에서 쓰는 은어같은것인가봄
|
||||||
|
- aim제품의 UI 통일성이 부족함
|
||||||
|
-> A set (Factory Modeler와 비슷한 시안) 제안
|
||||||
|
-> Q. B set는 그럼 뭐랑 비슷한가요? -> 개방감을 위주로 새로 한 시안인듯
|
||||||
|
( 못 물어보겠다 회의분위기가.. )
|
||||||
|
- UI / UX 제안인데, 설계 다 끝나가고 리뷰를 다음주에 하는데 지금 제안을 주는게 맞는것인가?
|
||||||
|
- UI / UX 제안서를 봤는데 기존이랑 크게 달라지는게 없는거 같은데?
|
||||||
|
( C# 프로그램에서 WebApp으로 바뀌는데 WebApp으로 구현하기엔 화면 하나에 표현되는 정보가 너무 많은 경우가 있는 것 같음. )
|
||||||
|
-> 이거에 대해서는 특별히 해결책이 제시되지도, 의논되지도 않았음
|
||||||
|
- 이번 NXMCS 프로젝트 부터는 퍼블리싱이 먼저 나오고 front 개발 진행되는 식으로
|
||||||
|
바뀔수 있으..려나?
|
||||||
|
- favorite 메뉴를 원래 C# UI Program에서 관리한거 같음. user table에 추가해서 이제 서버가 관리하는 식으로 바뀔 것 같음.
|
||||||
|
- 우측 information 탭 사용함
|
||||||
|
- properties -> select 한 grid item에 대한 properties를 나열해주는 우측 information
|
||||||
|
- 설비, 유닛별 메모기능 -> Excel 메모처럼 보여져야 한다?
|
||||||
|
|
||||||
|
화면 시안 A, B 중 맘에드는거 하나 골라놓자.
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
Q: 컨텍스트 메뉴는 한땀한땀 만든것인지?
|
||||||
|
: ㅇㅇ (노가다)
|
||||||
|
|
||||||
|
Online Remote는 Heart Beat 기능의 일종인가?
|
||||||
|
( Are you there? 같은 그런 느낌의 )
|
||||||
|
|
||||||
|
서버에게 정보 전송 -> reply 오거나 안오기까지
|
||||||
|
|
||||||
|
Wating Reply -> Success -> Success 상태를 알려주기 위한 문자열
|
||||||
|
-> Timeout
|
||||||
|
요런 순서로 버튼 클릭 시 동작이 잘 작동되고 있는지 알려주는 아이디어
|
||||||
|
progress button
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
JIRA 업데이트 해줄 것
|
||||||
|
|
||||||
|
화면설계 피드백
|
||||||
|
-
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
el, trans 이름
|
||||||
|
MCS Management 우클릭메뉴 없음
|
||||||
|
|
||||||
|
|
||||||
|
SECS Interface 화면
|
||||||
|
그리드에서 바로 데이터를 수정하는건 안쓰는걸로
|
||||||
|
보관함
|
||||||
|
|
||||||
|
프로퍼티 다시그리기
|
||||||
|
페이징 빼기
|
||||||
|
|
||||||
|
|
||||||
|
Resource Management
|
||||||
|
아이템에 따라 화면 다 내가 다 그려줘야함
|
||||||
|
State
|
||||||
|
다른화면 참고 필요
|
||||||
|
|
||||||
|
|
||||||
|
AlarmSpec management
|
||||||
|
버튼 다른화면이랑 비교해서 바꾸고
|
||||||
|
모달에서 정보 수정하도록
|
||||||
|
|
||||||
|
|
||||||
|
Alternate Storage management
|
||||||
|
트리에서 우클릭, 그리드에서 우클릭 (Alternate Storage 그리드)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Empty Carrier Balance Management
|
||||||
|
EQP ID가 PK라서 GroupName만 받아서 Group을 만들 수 없다.
|
||||||
|
DB Table 구조 excel 확인하면서 그려야함. (
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- MCS Application Management
|
||||||
|
→ 기존 구조를 따르되, 기존 Primary/Secondary에서 MCS 갯수대로 넘버링하고, UI로 표시함. (페이징)
|
||||||
|
→ 우클릭 메뉴에 대한 내용이 누락되어 확인하여 추가 예정.
|
||||||
|
- SECS Interface Management
|
||||||
|
→ AS-IS DB가 아닌 최신화 된 DB 컬럼 기준으로 설계할 것.
|
||||||
|
→ Grid Edit방식으로 설계했는데, 다른 Create/Modify/Delete 패턴을 참조하여 수정할 것.
|
||||||
|
→ SECS Reference 화면 설계 누락되어 확인하여 추가 예정.
|
||||||
|
- Resource Managment
|
||||||
|
→ 좌측 트리 클릭 대상(Type)에 따라 조회된 데이터가 출력 되는 화면이 다름. Main에서 넘어오는 경우도 있음. (논의 필요)
|
||||||
|
→ State 부분도 이미 결정된 내용을 따라 재설계할 것.
|
||||||
|
- AlarmSpec Manangement
|
||||||
|
→ Create/Modify/Delete 패턴 참조하여 재설계할 것.
|
||||||
|
- Alternate Storage Management
|
||||||
|
→ 기존 팝업 화면에서 한페이지에서 조작할 수 있도록 설계함. (Modal 방식이 나을지는 좀 더 고민 필요.)
|
||||||
|
→ Alternate Storage 그리드에 우클릭 컨텍스트 메뉴 추가.
|
||||||
|
→ Undo 제거, 순서 변경 기능 추가할 것.
|
||||||
|
- Recovery Dest Management
|
||||||
|
→ Alternate Storage Management와 동일한 UI 패턴으로 설계함.
|
||||||
|
- Empty Carrier Balance Management
|
||||||
|
→ Add New Group 버튼 클릭시 AS-IS와 동일하게 Modal로 추가할수 있도록 함. 단, Machine 정보도 같이 입력할 수 있도록 Modal창에 선택 화면 추가할 것.
|
||||||
|
→ 기타 이미 의사결정된 UI 요소들을 참조하여 재설계 할 것.
|
||||||
|
- Port Priorty Management
|
||||||
|
- MachineAlias Management
|
||||||
|
- UnitAlias Management
|
||||||
|
- User
|
||||||
|
→ User 메뉴, 권한 부분은 논의 필요.
|
||||||
|
- 이력 조회
|
||||||
|
→ Grid base의 단순한 구조로 변경할 것.
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
따라가기가 힘들다..
|
||||||
|
|
||||||
|
컨플런스 회의록 댓글에 변경되는 사항들에 대해 등록을 하겠음.
|
||||||
|
: 컨플런스 알람이 오는 것 같은데, 한번 알람왔을 때 확인 안하면 알람표식이 꺼지는거같음.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
반응형 화면 대응
|
||||||
|
→ 현재, 가로 사이즈 1280 이하 디바이스에서는 대응하지 않는 문제가 있음.
|
||||||
|
→ 1280 이하에서는 상단 메뉴 위치를 왼쪽에 대응 하는 방식으로 적용한다.
|
||||||
|
|
||||||
|
퍼블리싱 우선순위
|
||||||
|
→ 현재, 메뉴 기준으로 우선순위가 설정되어 있고, 그에 따라 개발 계획이 잡혀있음.
|
||||||
|
→ 레이아웃 → 메뉴 순으로 개발 우선순위를 두어야 함.
|
||||||
|
|
||||||
|
- Client 개발
|
||||||
|
→ 소스 충돌 방지 위해 퍼블리싱 소스를 Tag Branch단위로 관리한다.
|
||||||
|
( )
|
||||||
|
→ 화면 개발시 이를 참고하여 개발 한다.
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
Jira에 하위 일감을 그때그때 잡은 job에 추가해서 진행
|
||||||
|
|
||||||
|
sprint5 시작할 때 개발자 추가 투입 검토 예정
|
||||||
|
|
||||||
|
모달 기존 WFL거 말고 새로 만들어서 씀
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
1. 모달창 전부 제대로 그리기
|
||||||
|
2. 우측 properties 창 properties 아닌거 같은것들 수정
|
||||||
|
( 전정현선임 69page )
|
||||||
|
3. Alias가 Unit, Port, Zone, Equipment 네가지로 나뉘어짐.
|
||||||
|
( 네개를 한 화면에서 할 수 있을까? )
|
||||||
|
4. History 새로 그리기 (EAS 화면 기준으로)
|
||||||
|
( The Latest: 10초, 30초, 1분, 5분, 10분, 30분 )
|
||||||
|
( 검색시간 제한이 필요함. 너무 많은 데이터를 조회하면 안됨 )
|
||||||
|
( 하이닉스는 10분 초과 시 confirm 화면을 한번 띄움 )
|
||||||
|
|
||||||
|
http://211.60.157.241:8090/pages/viewpage.action?pageId=50075248
|
||||||
|
History 검색조건 중요도 순서
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
- UX는 비슷하게, UI는 새롭게 (????)
|
||||||
|
- 동적 화면 구성에 대해 고민해봐라 (????)
|
||||||
|
- Multi Select 방식을 고려해봐라 (???????)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
- 플랫폼개발팀에서 만든 로그뷰어를 써야한다. ( 로그뷰어 개발이 아니고 있던 플랫폼에 사용가능한 상태인지 확인하고 적용할 것 )
|
||||||
|
|
||||||
|
- 원래 있던 버튼, 바로가기 등이 없어질 경우 Relation Menu 등을 통해 찾아갈 수 있는 방향으로 함.
|
||||||
|
|
||||||
|
- MCS는 기준정보가 정해지기 전에 레이아웃 모델링을 한다.
|
||||||
|
( 레이아웃을 먼저 그리고 나서야 설비모델링 등록을 할 수 있다 )
|
||||||
|
: 레이아웃 그리는 곳에서 설비를 먼저 등록을 하고 레이아웃에 등록된 데이터를 DB에 있는 실제데이터랑 매핑을 하는 방식임
|
||||||
|
|
||||||
|
- 화면에서 공통적으로 쓰는 버튼같은것들은 템플릿을 동일하게 맞춰주면 좋겠음.
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
#### 1. 전달 받은 소스 및 설치 파일
|
||||||
|
1. JDK1.7 이상 ( 32bit 필요)
|
||||||
|
- jdk-8u381-windows-i586.exe
|
||||||
|
2. Tibco 8.3 이상 ( 32bit 필요)
|
||||||
|
- TIB_rv_8.4.3_win_x86_vc10.zip
|
||||||
|
3. MCS_TM18_개발환경구성
|
||||||
|
1). DATABASE
|
||||||
|
- database script file
|
||||||
|
2). SERVER
|
||||||
|
- eclipse.zip → IDE
|
||||||
|
- TM18_server.zip → config setup 되어 있는 workspace
|
||||||
|
3). UI
|
||||||
|
- layout → 기존 사용하는 모델링 layout
|
||||||
|
- TM18_client.zip → client setup 및 실행 파일
|
||||||
|
|
||||||
|
#### 2. 설치
|
||||||
|
- JDK 설치
|
||||||
|
- TibRV 설치
|
||||||
|
- Eclipse 압축풀기
|
||||||
|
|
||||||
|
#### 3. DB Set
|
||||||
|
- Oracle 11g 설치
|
||||||
|
- Script를 통해 테이블 생성 및 더미 데이터 추가
|
||||||
|
( CreateTableScript_TM18.sql 실행, TM18 Insert Script.sql 실행 )
|
||||||
|
주의사항: TM18 Insert Script.sql은 파일크기가 너무 커서 sql devleopment에서 못염
|
||||||
|
( IOExcepion 발생 ) 텍스트 에디터에서 연 다음 분할해서 실행시켜야함 (예를들어 10만줄씩?)
|
||||||
|
|
||||||
|
#### 4. 환경설정
|
||||||
|
![[2023-11-08 MCS 교육 필기]]
|
||||||
|
eclipse 실행
|
||||||
|
- workspace 위치 → TM18_server.zip 압축푼 디렉토리
|
||||||
|
- greenmcs-entry > config > TRANS4 > startup > interface.properties 수정 하고 저장
|
||||||
|
```xml
|
||||||
|
//interface.properties
|
||||||
|
..
|
||||||
|
## Basic
|
||||||
|
product=GREENMCS
|
||||||
|
site=TIANMA
|
||||||
|
fab=TM18
|
||||||
|
environment=COMMON --> environment=자신의 고유한 명칭으로 변경 ex) environment=JIKIM
|
||||||
|
|
||||||
|
|
||||||
|
..
|
||||||
|
..
|
||||||
|
#LOCAL
|
||||||
|
server.domain.host=TIANMA.TM18.MES.COMMON.FAB.TEMsvr -> TIANMA.TM18.MES.JIKIM.FAB.TEMsvr
|
||||||
|
server.domain.mcs.host=TIANMA.TM18.MCS.COMMON.FAB.HIFsvr -> TIANMA.TM18.MCS.JIKIM.FAB.HIFsvr
|
||||||
|
```
|
||||||
|
|
||||||
|
UI setup
|
||||||
|
UI > TM18_client > plugins > kr.co.aim.greenmcs.client.custom_1.0.1.20151013 > config_TM18 > ui-interface.xml 수정
|
||||||
|
|
||||||
|
```xml
|
||||||
|
//ui-interface.xml
|
||||||
|
..
|
||||||
|
<!-- destination -->
|
||||||
|
<bean id="serverSenderDestination" class="kr.co.aim.greenmcs.communication.msb.tibrv.QueueDestination">
|
||||||
|
<property name="name"><value>GREENMCS.TIANMA.TM18.COMMON.UI.LISTENER</value></property> -> GREENMCS.TIANMA.TM18.JIKIM.UI.LISTENER
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="serverListenerDestination" class="kr.co.aim.greenmcs.communication.msb.tibrv.HostNameQueueDestination" init-method="init">
|
||||||
|
<property name="name"><value>GREENMCS.TIANMA.TM18.COMMON.UI.SENDER.ALL.#{host}</value></property> -> GREENMCS.TIANMA.TM18.JIKIM.UI.SENDER.ALL.#{host}
|
||||||
|
</bean>
|
||||||
|
<bean id="allServerListenerDestination" class="kr.co.aim.greenmcs.communication.msb.tibrv.HostNameQueueDestination" init-method="init">
|
||||||
|
<property name="name"><value>GREENMCS.TIANMA.TM18.COMMON.UI.SENDER.ALL</value></property> -> GREENMCS.TIANMA.TM18.JIKIM.UI.SENDER.ALL
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
..
|
||||||
|
```
|
||||||
|
1. 수정후 [kr.co](http://kr.co/).aim.greenmcs.client.custom_1.0.1.20151013 폴더를 압축
|
||||||
|
|
||||||
|
2. 기존 [kr.co](http://kr.co/).aim.greenmcs.client.custom_1.0.1.20151013.jar 삭제
|
||||||
|
3. [kr.co](http://kr.co/).aim.greenmcs.client.custom_1.0.1.20151013.zip → 확장자 jar로 변경
|
||||||
|
4. exe 실행
|
||||||
|
1. plugin 어쩌구 저쩌구 에러가 발생하는 경우, [장원석](http://211.60.157.241:8090/display/~jhzhang) 책임에게 문의
|
||||||
|
5. Default 계정
|
||||||
|
1. common/common
|
||||||
|
|
||||||
|
|
||||||
|
6. . Java Project 설정
|
||||||
|
- workspace는 그냥 편한대다 만듬
|
||||||
|
- 그 워크스페이스에 프로젝트들 등록하고 진행하면 됨.
|
||||||
|
( run configuration은 전달받은 이클립스에 다 등록되어 있음 )
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"_joins":[],"_contexts":[],"_links":[],"_sort":{"field":"rank","asc":false,"group":false,"recursive":false},"_template":"","_templateName":"","defaultSticker":"","readMode":false}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
컨트롤러는 **클라이언트 요청을 처리**하는 역할을 합니다.
|
||||||
|
HTTP 요청을 받아 적절한 서비스로 전달하고, 서비스에서 처리된 결과를 클라이언트에게 반환합니다.
|
||||||
|
`@Controller()` 데코레이터로 정의합니다.
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
모듈은 NestJS 애플리케이션의 기본적인 빌딩 블록입니다.
|
||||||
|
각 모듈은 관련된 컴포넌트(서비스, 컨트롤러 등)를 그룹화하여 애플리케이션의 기능을 모듈화합니다.
|
||||||
|
`@Module()` 데코레이터로 정의하며, 하나의 애플리케이션은 여러 모듈로 구성될 수 있습니다.
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
nestjs는 express를 기반으로 구동되며
|
||||||
|
express에 기본적인 뼈대를 만들어놓은 형태
|
||||||
|
|
||||||
|
- 너무나도 자유도가 높은 nodejs의 단점을 보완해줌
|
||||||
|
- 아주 좋은 아키텍처와 구조를 가짐.
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
파이프는 데이터 변환 및 유효성 검사에 사용됩니다.
|
||||||
|
예를 들어, 들어오는 데이터가 올바른 형식인지 검증하거나, 데이터를 특정 형식으로 변환하는 데 사용됩니다.
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue