๐Ÿข Enterprise Microservices Stack

12 min read
go grpc kubernetes istio postgresql mongodb kafka redis prometheus grafana gitlab-ci terraform microservices cloud-native enterprise

๋Œ€๊ทœ๋ชจ ํŠธ๋ž˜ํ”ฝ๊ณผ ๋ณต์žกํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์œ„ํ•œ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜ - Go, gRPC, Kubernetes๋กœ ๊ตฌ์ถ•ํ•˜๋Š” ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ์‹œ์Šคํ…œ

๐Ÿข Enterprise Microservices Stack

๋Œ€๊ทœ๋ชจ ํŠธ๋ž˜ํ”ฝ๊ณผ ๋ณต์žกํ•œ ๋น„์ฆˆ๋‹ˆ์Šค๋ฅผ ์œ„ํ•œ ๊ฒ€์ฆ๋œ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜
"Build for millions, designed for complexity" - ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ๊ธ‰ ํ™•์žฅ์„ฑ๊ณผ ์•ˆ์ •์„ฑ


๐ŸŽฏ ์ด ์Šคํƒ์ด ์ ํ•ฉํ•œ ๊ฒฝ์šฐ

โœ… ์ถ”์ฒœํ•˜๋Š” ๊ฒฝ์šฐ

  • ์ผ์ผ ์ˆ˜๋ฐฑ๋งŒ ์š”์ฒญ ์ฒ˜๋ฆฌ ํ•„์š”
  • 100๋ช… ์ด์ƒ์˜ ๊ฐœ๋ฐœํŒ€์ด ๋™์‹œ ์ž‘์—…
  • ๋ณต์žกํ•œ ๋„๋ฉ”์ธ ๋กœ์ง๊ณผ ๋‹ค์–‘ํ•œ ์„œ๋น„์Šค ์šด์˜
  • 99.9% ์ด์ƒ์˜ ๊ฐ€์šฉ์„ฑ ์š”๊ตฌ์‚ฌํ•ญ
  • ๊ทœ์ • ์ค€์ˆ˜์™€ ๊ฐ์‚ฌ ์ถ”์  ํ•„์ˆ˜

โŒ ๋‹ค๋ฅธ ์Šคํƒ์„ ๊ณ ๋ คํ•ด์•ผ ํ•  ๊ฒฝ์šฐ

  • 10๋ช… ์ดํ•˜ ํŒ€ โ†’ Modern SaaS Stack
  • ๋‹จ์ˆœํ•œ CRUD ์•ฑ โ†’ Monolithic ์•„ํ‚คํ…์ฒ˜
  • ๋น„์šฉ ๋ฏผ๊ฐํ•œ ์Šคํƒ€ํŠธ์—… โ†’ Serverless Stack

๐Ÿงฉ ํ•ต์‹ฌ ๊ตฌ์„ฑ์š”์†Œ

๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ๋ ˆ์ด์–ด

// ์„œ๋น„์Šค ๊ฐ„ ํ†ต์‹  (gRPC) type OrderService struct { userClient user.UserServiceClient productClient product.ProductServiceClient paymentClient payment.PaymentServiceClient kafkaProducer *kafka.Producer } func (s *OrderService) CreateOrder(ctx context.Context, req *OrderRequest) (*OrderResponse, error) { // ๋ถ„์‚ฐ ํŠธ๋žœ์žญ์…˜ (Saga Pattern) saga := s.sagaOrchestrator.StartSaga(ctx, "create-order") // 1. ์‚ฌ์šฉ์ž ๊ฒ€์ฆ user, err := s.userClient.GetUser(ctx, &user.GetUserRequest{Id: req.UserId}) saga.AddCompensation(func() { /* rollback logic */ }) // 2. ์žฌ๊ณ  ํ™•์ธ inventory, err := s.productClient.CheckInventory(ctx, req.Items) saga.AddCompensation(func() { /* restore inventory */ }) // 3. ๊ฒฐ์ œ ์ฒ˜๋ฆฌ payment, err := s.paymentClient.ProcessPayment(ctx, req.Payment) saga.AddCompensation(func() { /* refund payment */ }) // 4. ์ด๋ฒคํŠธ ๋ฐœํ–‰ event := &OrderCreatedEvent{ OrderId: order.Id, UserId: user.Id, Amount: payment.Amount, } s.kafkaProducer.Produce("order-events", event) return &OrderResponse{Order: order}, nil } 

์„œ๋น„์Šค ๋ฉ”์‹œ (Istio)

# Istio ํŠธ๋ž˜ํ”ฝ ๊ด€๋ฆฌ apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: order-service spec: hosts: - order-service http: - match: - headers: x-version: exact: v2 route: - destination: host: order-service subset: v2 weight: 100 - route: - destination: host: order-service subset: v1 weight: 90 - destination: host: order-service subset: v2 weight: 10 # Canary ๋ฐฐํฌ timeout: 30s retries: attempts: 3 perTryTimeout: 10s 

๋ฐ์ดํ„ฐ ์•„ํ‚คํ…์ฒ˜

# ํด๋ฆฌ๊ธ€๋ž ํผ์‹œ์Šคํ„ด์Šค databases: postgresql: - users_db # ํŠธ๋žœ์žญ์…˜ ๋ฐ์ดํ„ฐ - orders_db # ์ฃผ๋ฌธ ๊ด€๋ฆฌ - billing_db # ๊ฒฐ์ œ ์ •๋ณด mongodb: - products_db # ์ œํ’ˆ ์นดํƒˆ๋กœ๊ทธ - analytics_db # ๋ถ„์„ ๋ฐ์ดํ„ฐ redis: - session_cache # ์„ธ์…˜ ๊ด€๋ฆฌ - rate_limiter # API ์ œํ•œ - pub_sub # ์‹ค์‹œ๊ฐ„ ๋ฉ”์‹œ์ง• elasticsearch: - search_index # ์ „๋ฌธ ๊ฒ€์ƒ‰ - logs_index # ๋กœ๊ทธ ์ง‘๊ณ„ 

์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆฌ๋ฐ

// Kafka ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ type EventProcessor struct { consumer *kafka.Consumer handlers map[string]EventHandler } func (p *EventProcessor) ProcessEvents() { for { msg, err := p.consumer.ReadMessage(-1) if err != nil { continue } // ์ด๋ฒคํŠธ ํƒ€์ž…๋ณ„ ์ฒ˜๋ฆฌ handler, exists := p.handlers[msg.Topic] if exists { // ๋ฉฑ๋“ฑ์„ฑ ๋ณด์žฅ if err := handler.Handle(msg); err != nil { // Dead Letter Queue๋กœ ์ „์†ก p.sendToDLQ(msg, err) } } p.consumer.CommitMessage(msg) } } 

๐Ÿ’ฐ ์ธํ”„๋ผ ๋น„์šฉ ๋ถ„์„

| ์ปดํฌ๋„ŒํŠธ | ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ | ํ”„๋กœ๋•์…˜ | ๊ณ ๊ฐ€์šฉ์„ฑ ๊ตฌ์„ฑ | |----------|-------------|----------|--------------| | Kubernetes (EKS/GKE) | $200/์›”(3 nodes) | $1,000/์›”(10 nodes) | $3,000/์›”(30 nodes) | | ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค | $300/์›” | $2,000/์›” | $6,000/์›” | | Kafka | $150/์›” | $800/์›” | $2,500/์›” | | ๋ชจ๋‹ˆํ„ฐ๋ง | $100/์›” | $500/์›” | $1,500/์›” | | ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ/CDN | $50/์›” | $300/์›” | $1,000/์›” | | ๋ฐฑ์—…/DR | $100/์›” | $500/์›” | $2,000/์›” | | ์ด๊ณ„ | ~$900/์›” | ~$5,100/์›” | ~$16,000/์›” |

์ธ๋ ฅ ๋น„์šฉ (ํ•„์ˆ˜ ๊ณ ๋ ค์‚ฌํ•ญ)

  • DevOps ์—”์ง€๋‹ˆ์–ด: 2-3๋ช…
  • SRE: 2-3๋ช…
  • ํ”Œ๋žซํผ ์—”์ง€๋‹ˆ์–ด: 1-2๋ช…
  • ์—ฐ๊ฐ„ ์ธ๊ฑด๋น„: $500K - $1M

๐Ÿš€ ๊ตฌํ˜„ ๋กœ๋“œ๋งต

Phase 1: ๊ธฐ๋ฐ˜ ๊ตฌ์ถ• (1-2๊ฐœ์›”)

# Kubernetes ํด๋Ÿฌ์Šคํ„ฐ ํ”„๋กœ๋น„์ €๋‹ terraform init terraform plan -var-file=environments/production.tfvars terraform apply # ๊ธฐ๋ณธ ์„œ๋น„์Šค ๋ฐฐํฌ kubectl apply -f namespaces/ kubectl apply -f rbac/ helm install istio istio/base helm install prometheus prometheus-community/kube-prometheus-stack 

Phase 2: ํ•ต์‹ฌ ์„œ๋น„์Šค (2-3๊ฐœ์›”)

// ์„œ๋น„์Šค ํ…œํ”Œ๋ฆฟ type BaseService struct { logger *zap.Logger metrics *prometheus.Registry tracer trace.Tracer health *health.Handler rateLimit *redis.Client } func NewService(name string) *BaseService { return &BaseService{ logger: logger.NewLogger(name), metrics: metrics.NewRegistry(name), tracer: tracing.NewTracer(name), health: health.NewHandler(), } } 

Phase 3: ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ (1-2๊ฐœ์›”)

# Kafka ํ† ํ”ฝ ์„ค๊ณ„ topics: - name: user-events partitions: 50 replication: 3 retention: 7d - name: order-events partitions: 100 replication: 3 retention: 30d - name: payment-events partitions: 50 replication: 3 retention: 90d 

Phase 4: ๊ด€์ธก์„ฑ ๊ตฌ์ถ• (1๊ฐœ์›”)

// ๋ถ„์‚ฐ ์ถ”์  func (s *OrderService) CreateOrder(ctx context.Context, req *OrderRequest) (*OrderResponse, error) { span, ctx := opentracing.StartSpanFromContext(ctx, "CreateOrder") defer span.Finish() // ๋ฉ”ํŠธ๋ฆญ ์ˆ˜์ง‘ timer := prometheus.NewTimer(orderCreationDuration) defer timer.ObserveDuration() // ๊ตฌ์กฐํ™”๋œ ๋กœ๊น… logger := s.logger.With( zap.String("order_id", req.OrderId), zap.String("user_id", req.UserId), zap.Float64("amount", req.Amount), ) logger.Info("Creating order") // ... ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง } 

๐Ÿ—๏ธ ์•„ํ‚คํ…์ฒ˜ ํŒจํ„ด

Domain-Driven Design

services/ โ”œโ”€โ”€ user-service/ โ”‚ โ”œโ”€โ”€ domain/ # ๋„๋ฉ”์ธ ๋ชจ๋ธ โ”‚ โ”œโ”€โ”€ application/ # ์œ ์Šค์ผ€์ด์Šค โ”‚ โ”œโ”€โ”€ infrastructure/ # ์™ธ๋ถ€ ์—ฐ๋™ โ”‚ โ””โ”€โ”€ interfaces/ # API ๋ ˆ์ด์–ด โ”œโ”€โ”€ order-service/ โ”œโ”€โ”€ product-service/ โ”œโ”€โ”€ payment-service/ โ””โ”€โ”€ notification-service/ 

Circuit Breaker ํŒจํ„ด

// Hystrix ์Šคํƒ€์ผ Circuit Breaker type CircuitBreaker struct { failureThreshold int timeout time.Duration resetTimeout time.Duration } func (cb *CircuitBreaker) Call(fn func() error) error { if cb.state == Open { if time.Since(cb.lastFailure) > cb.resetTimeout { cb.state = HalfOpen } else { return ErrCircuitOpen } } err := fn() if err != nil { cb.recordFailure() if cb.failures > cb.failureThreshold { cb.state = Open cb.lastFailure = time.Now() } return err } cb.recordSuccess() return nil } 

CQRS + Event Sourcing

// Command ์ฒ˜๋ฆฌ type CreateOrderCommand struct { OrderID string UserID string Items []OrderItem Timestamp time.Time } // Event ์ €์žฅ type OrderCreatedEvent struct { AggregateID string Version int Payload interface{} Timestamp time.Time } // Query ๋ชจ๋ธ (Read DB) type OrderProjection struct { OrderID string UserName string TotalAmount float64 Status string UpdatedAt time.Time } 

๐Ÿ”„ ๊ธฐ์ˆ  ๋Œ€์•ˆ

์–ธ์–ด๋ณ„ ๋ณ€ํ˜•

| ์ปดํฌ๋„ŒํŠธ | Go ์Šคํƒ | Java ์Šคํƒ | Node.js ์Šคํƒ | |----------|---------|-----------|--------------| | ํ”„๋ ˆ์ž„์›Œํฌ | Gin/Echo | Spring Boot | Express/Fastify | | RPC | gRPC | gRPC/REST | GraphQL | | ๋ฉ”์‹œ์ง• | Kafka | RabbitMQ | NATS | | ๋ชจ๋‹ˆํ„ฐ๋ง | Prometheus | Micrometer | PM2 |

ํด๋ผ์šฐ๋“œ ๋„ค์ดํ‹ฐ๋ธŒ ๋Œ€์•ˆ

# AWS ๋„ค์ดํ‹ฐ๋ธŒ aws: compute: EKS service_mesh: App Mesh api_gateway: API Gateway messaging: Kinesis/SQS database: Aurora/DynamoDB cache: ElastiCache # GCP ๋„ค์ดํ‹ฐ๋ธŒ gcp: compute: GKE service_mesh: Anthos Service Mesh api_gateway: Apigee messaging: Pub/Sub database: Spanner/Firestore cache: Memorystore 

๐Ÿ† ์‹ค์ œ ์ ์šฉ ์‚ฌ๋ก€

Uber

  • ๊ทœ๋ชจ: ์ˆ˜์ฒœ ๊ฐœ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค
  • ํŠธ๋ž˜ํ”ฝ: ์ดˆ๋‹น ์ˆ˜๋ฐฑ๋งŒ ์š”์ฒญ
  • ํŠน์ง•: ์ž์ฒด RPC ํ”„๋ ˆ์ž„์›Œํฌ (TChannel)

Netflix

  • ๊ทœ๋ชจ: 700+ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค
  • ํŠน์ง•: Chaos Engineering ์„ ๊ตฌ์ž
  • ๋„๊ตฌ: Eureka, Hystrix, Zuul

Airbnb

  • ์ด์ „: Ruby Monolith
  • ํ˜„์žฌ: ์„œ๋น„์Šค ์ง€ํ–ฅ ์•„ํ‚คํ…์ฒ˜
  • ํŠน์ง•: GraphQL Federation

๐Ÿ“š ํ•„์ˆ˜ ํ•™์Šต ์ž๋ฃŒ

๋„์„œ

  • "Building Microservices" - Sam Newman
  • "Microservices Patterns" - Chris Richardson
  • "Site Reliability Engineering" - Google

์˜จ๋ผ์ธ ๋ฆฌ์†Œ์Šค

์ธ์ฆ ๋ฐ ๊ต์œก

  • CKA (Certified Kubernetes Administrator)
  • CKAD (Certified Kubernetes Application Developer)
  • AWS/GCP/Azure Solutions Architect

๐Ÿ’ฌ ํ˜„์—… ๊ฐœ๋ฐœ์ž ์กฐ์–ธ

"๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋Š” ์กฐ์ง ๊ตฌ์กฐ๋ฅผ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. Conway's Law๋ฅผ ๋ฌด์‹œํ•˜๋ฉด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ํŒ€ ๊ตฌ์กฐ๋ถ€ํ„ฐ ๋ฐ”๊พธ์„ธ์š”." - @microservices_architect

"์ฒ˜์Œ๋ถ€ํ„ฐ ๋ชจ๋“  ๊ฑธ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋กœ ๋งŒ๋“ค์ง€ ๋งˆ์„ธ์š”. Monolith First๋กœ ์‹œ์ž‘ํ•˜๊ณ  ํ•„์š”ํ•  ๋•Œ ๋ถ„๋ฆฌํ•˜์„ธ์š”." - @pragmatic_dev

"๋ถ„์‚ฐ ํŠธ๋ ˆ์ด์‹ฑ ์—†์ด๋Š” ๋””๋ฒ„๊น…์ด ์ง€์˜ฅ์ž…๋‹ˆ๋‹ค. Jaeger๋‚˜ Zipkin์€ ์„ ํƒ์ด ์•„๋‹ˆ๋ผ ํ•„์ˆ˜์˜ˆ์š”." - @sre_expert

"๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์ด ์ œ์ผ ์–ด๋ ค์›Œ์š”. Saga ํŒจํ„ด ์ œ๋Œ€๋กœ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ 6๊ฐœ์›” ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค." - @distributed_systems_dev


โšก ์„ฑ๋Šฅ ์ตœ์ ํ™”

์„œ๋น„์Šค ๊ฐ„ ํ†ต์‹  ์ตœ์ ํ™”

// Connection Pooling var grpcConnPool = sync.Map{} func getGRPCConnection(address string) (*grpc.ClientConn, error) { if conn, ok := grpcConnPool.Load(address); ok { return conn.(*grpc.ClientConn), nil } conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithKeepaliveParams(keepalive.ClientParameters{ Time: 10 * time.Second, Timeout: 3 * time.Second, PermitWithoutStream: true, }), grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(10 * 1024 * 1024), // 10MB ), ) grpcConnPool.Store(address, conn) return conn, err } 

์บ์‹ฑ ์ „๋žต

// ๋‹ค์ธต ์บ์‹ฑ type CacheLayer struct { l1Cache *ristretto.Cache // In-memory l2Cache *redis.Client // Redis l3Cache *memcached.Client // Memcached } func (c *CacheLayer) Get(key string) (interface{}, error) { // L1 ์ฒดํฌ if val, found := c.l1Cache.Get(key); found { return val, nil } // L2 ์ฒดํฌ val, err := c.l2Cache.Get(key).Result() if err == nil { c.l1Cache.Set(key, val, 1) return val, nil } // L3 ์ฒดํฌ // ... ๊ตฌํ˜„ } 

๐Ÿšจ ์šด์˜ ๊ณ ๋ ค์‚ฌํ•ญ

์žฅ์•  ๋Œ€์‘

  1. Graceful Degradation: ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์šฐ์„  ๋ณด์žฅ
  2. Circuit Breaker: ์—ฐ์‡„ ์žฅ์•  ๋ฐฉ์ง€
  3. Bulkhead: ๋ฆฌ์†Œ์Šค ๊ฒฉ๋ฆฌ
  4. Timeout/Retry: ์ ์ ˆํ•œ ์„ค์ • ํ•„์ˆ˜

๋ณด์•ˆ

  • mTLS๋กœ ์„œ๋น„์Šค ๊ฐ„ ํ†ต์‹  ์•”ํ˜ธํ™”
  • RBAC์œผ๋กœ ์„ธ๋ฐ€ํ•œ ๊ถŒํ•œ ๊ด€๋ฆฌ
  • Secret ๊ด€๋ฆฌ (Vault, Sealed Secrets)
  • Zero Trust Network ๊ตฌํ˜„

์ปดํ”Œ๋ผ์ด์–ธ์Šค

  • ๊ฐ์‚ฌ ๋กœ๊ทธ ์ค‘์•™ํ™”
  • ๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™” (์ „์†ก/์ €์žฅ)
  • GDPR/PCI-DSS ์ค€์ˆ˜
  • ์ •๊ธฐ ๋ณด์•ˆ ๊ฐ์‚ฌ

๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ: 2025-01-28
๊ธฐ์—ฌํ•˜๊ธฐ: GitHub์—์„œ ํŽธ์ง‘

Found this helpful? Share it with others!
Tweet

๐Ÿ”— Related Content

You might also be interested in these articles

๐Ÿ—๏ธ stack

๐Ÿค– AI-Powered App Stack

ํ”„๋กœ๋•์…˜ ๋ ˆ๋ฒจ AI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์ถ•์„ ์œ„ํ•œ ๊ฒ€์ฆ๋œ ๊ธฐ์ˆ  ์Šคํƒ - LangChain, FastAPI, Vector DB๋กœ RAG ์‹œ์Šคํ…œ ๊ตฌํ˜„

11 min read
python, fastapi+13
Read more
๐Ÿข company

๐Ÿข Canva ๊ธฐ์ˆ  ์Šคํƒ ๋ถ„์„

์บ”๋ฐ”๊ฐ€ 1์–ต ๋ช… ์ด์ƒ์˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ์‰ฝ๊ณ  ๊ฐ•๋ ฅํ•œ ๋””์ž์ธ ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ธฐ์ˆ  ์Šคํƒ ์‹ฌ์ธต ๋ถ„์„ - Java, TypeScript, AWS๋กœ ๊ตฌ์ถ•ํ•œ ๋Œ€๊ทœ๋ชจ ๋””์ž์ธ ํ”Œ๋žซํผ

35 min read
canva, java+10
Read more
๐Ÿข company

๐Ÿข Stripe ๊ธฐ์ˆ  ์Šคํƒ ๋ถ„์„

์ŠคํŠธ๋ผ์ดํ”„๊ฐ€ ์ „ ์„ธ๊ณ„ ์ˆ˜๋ฐฑ๋งŒ ๋น„์ฆˆ๋‹ˆ์Šค์˜ ๊ฒฐ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ์ˆ  ์Šคํƒ ์‹ฌ์ธต ๋ถ„์„ - Ruby, Go, Java๋กœ ๊ตฌ์ถ•ํ•œ ๊ธˆ์œต ์ธํ”„๋ผ์˜ ๋ฏธ๋ž˜

37 min read
stripe, ruby+11
Read more
๐Ÿข company

๐Ÿข Uber ๊ธฐ์ˆ  ์Šคํƒ ๋ถ„์„

์šฐ๋ฒ„๊ฐ€ ๋งค์ผ 2,500๋งŒ ๊ฑด์˜ ๋ผ์ด๋“œ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋งค์นญํ•˜๋Š” ๊ธฐ์ˆ  ์Šคํƒ ์‹ฌ์ธต ๋ถ„์„ - Go, Java, Node.js๋กœ ๊ตฌ์ถ•ํ•œ ๊ธ€๋กœ๋ฒŒ ์‹ค์‹œ๊ฐ„ ๋งˆ์ผ“ํ”Œ๋ ˆ์ด์Šค

17 min read
uber, microservices+12
Read more
๐Ÿข company

๐Ÿข ๋‹น๊ทผ๋งˆ์ผ“ ๊ธฐ์ˆ  ์Šคํƒ ๋ถ„์„

๋‹น๊ทผ๋งˆ์ผ“์ด ๋™๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ํ˜์‹ ํ•˜๋ฉฐ ์œ ๋‹ˆ์ฝ˜์œผ๋กœ ์„ฑ์žฅํ•œ ๊ธฐ์ˆ  ์Šคํƒ ์‹ฌ์ธต ๋ถ„์„ - Ruby on Rails, Kotlin, Swift๋กœ ๋งŒ๋“  ํ•˜์ดํผ๋กœ์ปฌ ํ”Œ๋žซํผ

53 min read
karrot, daangn+9
Read more

Found this helpful?

Help us improve this content by contributing on GitHub or sharing your feedback with the community.