| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
- 오블완
- GoF
- 보안
- MSA
- goland
- typescript
- GIT
- Thymeleaf Expression Object
- Infra
- golang
- blank import
- 통합 로깅 시스템
- 티스토리챌린지
- elasticsearch
- 디자인패턴
- Intellij
- RDS
- Kubernetes
- esbuild
- AI
- 캡슐화
- database/sql
- 구조체
- 관측 가능성
- AWS
- javascript
- logging
- go
- go-sql-driver
- Custom Dialect
- Today
- Total
목록Information Technology (329)
Fall in IT.
Thymeleaf를 사용하다 보면 Controller가 Model에 직접 담아주지 않은 데이터나, 공통적으로 사용하는 유틸리티 함수(날짜 포맷팅, 금액 변환 등)를 템플릿 어디에서나 자유롭게 호출하고 싶은 경우가 생깁니다.단순히 데이터를 화면에 출력하는 것을 넘어, 템플릿의 가독성을 높이고 유지보수를 효율적으로 만들어주는 전역 유틸리티 활용법 3가지를 정리합니다.1. Thymeleaf Expression Object (Custom Dialect)Thymeleaf의 철학에 가장 부합하는 정석적인 방법입니다. 사용자가 직접 정의한 객체를 {#객체명} 형태로 사용할 수 있도록 등록하는 방식입니다.구현 단계유틸리티 서비스 작성: 실제 로직을 담당할 컴포넌트를 작성합니다.Dialect 및 Factory 구현: T..
서비스 보안을 강화하기 위해 가장 보편적으로 사용되는 방법은 2FA(2-Factor Authentication, 2단계 인증)입니다.오늘은 2FA의 핵심 기술 중 하나인 TOTP 방식의 OTP 인증 아키텍처와 그 작동 원리에 대해 정리해 보겠습니다. 1. 2FA(2단계 인증)란 무엇인가?2FA는 사용자가 로그인을 시도할 때, 서로 다른 두 가지 방식의 인증 요소를 결합하여 본인임을 확인하는 절차입니다.1차 인증: 지식 기반 요소 (ID/Password)2차 인증: 소유 기반 요소 (OTP 코드, 하드웨어 토큰) 또는 생체 기반 요소 (지문, FaceID 등)아이디와 비밀번호가 유출되더라도, 사용자가 물리적으로 소유한 기기(스마트폰 등)가 없다면 계정에 접근할 수 없도록 설계하는 것이 핵심입니다. 2. O..
개발 과정에서 '스택 오버플로우'나 '메모리 누수'와 같은 용어를 빈번하게 접하게 된다. 프로그램이 실행될 때 코드, 변수, 함수 등이 저장되는 메모리 공간의 구조를 이해하는 것은 중요하다.본 글은 프로그램 실행 시 사용되는 메모리 공간의 구조를 분석하고, 개발자가 이를 이해해야 하는 이유를 예제 코드와 함께 기술한다.1. 코드(Code) 영역코드 영역은 작성된 소스 코드가 컴파일된 기계어(Machine Code)가 저장되는 공간이다. 이 영역은 프로그램 시작 시 메모리에 로드되어 프로그램이 종료될 때까지 유지된다.특징: 실행 중 코드 변경을 방지하여 프로그램의 안정성을 확보하기 위해 읽기 전용(Read-Only)으로 설정되는 경우가 많다. CPU는 이 영역의 명령어를 순차적으로 읽어 실행한다.메모리 크..
전통적인 모놀리식(Monolithic) 아키텍처에서 마이크로소프트 아키텍처(MSA)로의 전환은 이제 거스를 수 없는 흐름이 되었다. MSA는 서비스의 독립적인 개발과 배포를 가능하게 하여 조직의 생산성을 극대화하는 강력한 장점을 가지고 있다. 하지만 서비스가 잘게 쪼개지고, 하나의 요청이 여러 서비스 간의 복잡한 네트워크 호출로 이어지면서 새로운 문제가 발생했다. 바로 시스템의 동작을 이해하고 추적하기가 극도로 어려워졌다는 점이다.과거 모놀리식 환경에서는 CPU, Memory 사용률과 같은 시스템 매트릭과 로그 파일만 잘 확인해도 장애의 원인을 비교적 쉽게 파악할 수 있었다. 그러나 MSA 환경에서는 문제가 발생했을 때, 수많은 서비스 중 어느 곳에서 문제가 시작되었고, 그 여파가 어디까지 미쳤는지 파악..
오늘은 많은 개발자들이 매일 사용하지만, 그 내부 동작까지는 깊이 생각해보지 않았을 '비밀번호 암호화'에 대해 이야기해보려고 합니다. bcrypt, rainbow table, salt 같은 키워드들, 어렴풋이 알고만 계셨나요? 이 글을 통해 개념을 확실히 정리하고 가시죠!지금 우리 서비스는 안전할까? - BCrypt와 Argon22025년 현재, 우리가 만드는 대부분의 서비스는 BCrypt 알고리즘으로 사용자의 비밀번호를 해시(hash)하고 있을 겁니다. 1999년에 개발되어 오랜 기간 안정성을 검증받은, 아주 훌륭한 '국민 알고리즘'이죠.하지만 기술은 계속 발전합니다. 2015년 열린 암호 해싱 대회에서 우승을 차지한 Argon2라는 새로운 강자가 등장했습니다. Argon2의 가장 큰 장점은 무엇일까요..
개발을 하다 보면 시간이 지날수록 연차는 쌓이는데, 스스로 실력이 크게 성장하지 못했다고 느낄 때가 있다.왜 이런 일이 생기는지 곰곰이 생각해봤다. 연차는 늘지만 실력이 정체되는 이유빠르게 아웃풋을 내야 하는 환경단기적인 결과물만 요구받다 보니 깊이 있는 고민이나 설계를 적게 한다.당장의 문제 해결에만 몰두문제를 근본적으로 해결하기보다, 눈앞의 버그나 이슈만 처리하는 데 급급하다.“이 정도면 됐다”는 안일함지금 당장은 돌아가니까, 더 나은 설계나 확장성은 미뤄둔다.코드가 성숙할 기회가 없는 환경프로젝트가 단기간에 끝나고 사라지거나, 장기적인 유지보수가 이루어지지 않는 경우 코드가 성숙될 수 없다.학습과 피드백이 없는 조직 문화보고 배우고 성장할 수 있는 동료가 없다면, 개인의 성장은 더딜 수밖에 없다. ..
Go에서 context.WithValue()를 사용해 값을 전달할 때, 습관적으로 string 타입을 key로 사용하곤 했습니다. 하지만 이 방식은 key 충돌과 같은 문제가 발생할 수 있습니다.이 글에서는 안전한 context key 사용법과 주의사항에 대해서 알아보겠습니다.string key 사용시 발생할 수 있는 문제const UserIdKey string = "user_id"func withUserId(ctx context.Context, user *User) context.Context { return context.WithValue(ctx, UserIdKey, user)}위의 코드는 go-staticcheck에서 경고를 발생시킨다.should not use built-in type string..
DDD(Domain Driven Design)를 적용하여 Go 프로젝트를 개발할 때, 데이터베이스에서 조회한 데이터를 도메인 엔티티로 복원하는 과정은 항상 수반되는 아주 귀찮은 작업이다.이 글에서는 엔티티의 캡슐화를 유지하면서 효율적으로 복원하는 방법에 대해 정리해보았다.Go에서 DB → DTO → Domain Entity로 복원하는 세 가지 방법과 각각의 장단점 그리고 마지막으로 Java(Spring boot + JPA)에서의 처리 방법을 비교해보겠다.먼저, 일반적인 Account Entity 구조를 살펴보자.// 계좌 엔티티type Account struct { id ID name string balance money.Money version int createdAt time.Time updatedA..
Go 언어로 Database에 접근하려고 할때, 보통 이런 코드가 들어간다.import ( "database/sql" _ "github.com/go-sql-driver/mysql")여기서 github.com/go-sql-driver/mysql은 MySQL 드라이버인데, 흥미로운 점은 _로 import 한다는 점이다.“어? 명시적으로 사용하지 않는걸 반드시 임포트해야 동작하게 만들어놨다고..?” 란 의문이 생긴다.이 부분에 대해서 그 이유와 동작 방식을 쉽게 풀어보겠다.1. Blank Import (_)의 의미Go에서 import _ “패키지”는 해당 패키지를 코드에서 직접 사용하지는 않지만, 패키지의 init() 함수는 실행되게 만든다.즉, _를 붙이면 명시적으로 패키지를 호출하여 사용하진 않지만, si..
DB 업데이트와 SQS 메시지 발송을 하나의 트랜잭션 즉, 원자적 단위로 묶을 수 없다.그 이유는관계형 데이터베이스 트랜잭션은 DB 내부에서만 원자성이 보장되고SQS(혹은 대부분의 메시지 큐)는 데이터베이스와의 2PC(분산 트랜잭션, XA 트랜잭션)을 지원하지 않기 때문이다.즉, 둘은 완전히 별도의 시스템이기 때문에 원자적 보장이 없으므로, 하나만 성공하거나 실패할 수 있는 상황이 생길 수 있다.나는 주로 어떤 방식으로 구현했는가? (어떤 선택을 했었더라..?)DB 업데이트 트랜잭션을 실행한다.트랜잭션 커밋에 성공하면 SQS 메시지를 전송한다.트랜잭션 커밋에 실패하면 SQS 메시지를 전송하지 않는다.SQS 메시지를 전송에 실패할 경우 DB에 기록하고 후처리가 가능하도록 한다.내가 선택한 방식에 대한 이유..
