직접 구축하기 vs 돈내고 쓰기

이성적으로는 돈 내고 쓰면서 빠르게 개발하는게 낫다는걸 알지만
하나하나 구축하려는 욕심이 든다
적정기준을 정해놓고 따르는게 좋을 것 같은데

서비스 구축을 하면서 사용해야 하는 서비스가 몇가지 있는데

  • 인프라
    • 그냥 서버.. linux, unix, windwos ..
    • k8s cluster
    • object storage
    • cdn
  • DevOps
    • 빌드
    • 배포
  • Logging & 모니터링
    • 로그수집
    • 모니터링
    • 알림

구축하는데 들어가는 비용이 이익을 상회하지 않는 경우
비용: 시간, 돈, 인력
이익: 만족감, 기술발전, 속도, 돈

비교

인프라

IDC에 서버 올려서 직접 구축하면 제일 싸긴하다… 효율적으로 사용할 수 없다.
초기비용이 크고 서버 관리하는 기술도 생각보다 어렵고
경험이 없으면 삽질을 엄청 많이 하게 된다
코드만 만지던 사람들이 생각도 못한 변수가…

그리고 서버를 코드화 할 수 없으면 곤란한 상황이 많이 발생한다.
메이저 클라우드 업체를 쓰면 서버를 완전 코드화할 수 있다.

  • AWS
  • GCP
  • Azure
  • Heroku

서버만 쓸 수도 있지만 클러스터까지 쓸 수도 있고

  • k8s
  • ecs

네이버 클라우드 등 국내 서비스는 안됨. XXX

CDN, ObjectStorage는 클라우드플레어 등 다른 회사를 써도 되고 메이저 클라우드를 써도 되는데 다 코드화가 가능하다.
코드화가 가능하면 인프라 구축이 매우 쉬워진다.
SI도 아닌데 한번 구축하면 끝이지 왜 환경을 재현해야 하냐고???? 하는 경우가 있는데

  • CloudFlare

인프라 코드화의 장점

  • 테스트 환경 구축: production 환경에
  • 서비스 확장이 간편: 인프라 규모를 확장할 때 오류 가능성이 낮다.
  • 테스트 자동화가

DevOps

위에 있는거에서 DevOps는 코드화 해서 쉽게 할 수 있고
githubaction같은 무료서비스도 많으니 그냥 써도 된다. 서버를 직접구축하면 조금 더 빠르긴한데 취향에 따라 마음대로 해도 되는 부분…
아직 돈내고 써서 엄청 좋아지는 서비스가 없다

  • kustomize
  • gitops
  • githubaction
  • gitlabaction?
  • drone
  • argocd
  • keel

로깅 & 모니터링

hadoop, elastic search, prometheus 거의 이 중 한쪽 생태계와 주변기술 아닐까

구축하는게 튜토리얼대로 하면 금방 할 수 있기도 한데…
서비스에 맞게 튜닝을 하려면 신경쓸게 많다.
생각보다 잘 안되는 편

어떻게 보면 진짜 비핵심적인 부분이기도 해서
진짜 필요한 부분에서는 직접 로그를 DB에 저장하던지 하고
전체적으로는 돈내고 써야하는 분야

sentry, datadog, … 등등 검색하면 많다

클라우드에서 기본 제공해주는 서비스는 대부분 ES, Hadoop 기반이고
커스터마이징이 불편해서 별도로 작업이 많이 필요하다.

[후기] 개발자 이직시 헤드헌터를 통하는 방법

매우 비추천한다

헤드헌터의 서비스(원론적으로)

구직자 대상

  • 이력서 첨삭
  • 연봉 조언
  • 채용정보 제공(기업소개)

채용기업 대상

  • 회사에서 필요한 인재 발굴
    • 경쟁사 직원
    • 구인구직사이트 노출되지 않은 사람
    • 이력서는 완성 돼 있지 않지만 역량이 맞는 사람
  • 채용공고 작성 및 컨설팅
  • 인재 관리 스킬 전수

헤드헌터의 보수

대강 이런 서비스를 제공 해 주고 채용인원 연봉의 5% ~ 10% ~ 20% 정도를 받아가는걸로 알려져 있다.
입사시 사이닝 약간.. 50만원? 5%??
3개월시 10%?? 20%???
6개월 또는 1년시 20%??
계약에 따라 다양하겠지만 최종적으로 정착하면 20%정도로 보면된다

연봉5천짜리면 20%만 받아도 1000만원 원룸소개하는 공인중개사가 들이는 노력과 그 전문성에 대한 보수에 비교 해 보자… 이정도면 변호사보다도 큰 것 같다)

헤드헌터의 스킬

괜찮은 헤드헌터는 HR은 좀 해봤을지 모른다
그런데 그건 신입채용시는 도움이 될지 모르나…
분야별 전문지식이 필요한 경력이직은 좀 얘기가 다르다.

각 기업에서 면접을 보기 전에
* 사전필터도 해 주고
* 인재 발굴도 해 줘야 하는데

요새는 워낙에 정보가 공개 돼 있다 보니 기업과 헤드헌터가 동시에 구직자에게 노출되고 있는 상황이다. 사람인 같은 서비스에서 구직자 검색이 가능한 것도 기업이나 헤더헌터나 마찬가지…
헤드헌터가 기업보다 더 좋은 데이터셋을 보유하고 있지 않다.

헤드헌터가 유용한 경우는
구직자가 먼저 컨텍하는게 아닌 그 반대의 경우다
블로그나 깃헙을 보고 스카웃 제의를 하는 경우
요즘 그런식으로 이직했다는 소식을 간혹 듣긴한다
링크드인도 있겠지만 국내에서는 이거 잘 꾸며놓는 개발자 본 적이 없어서

이력서 첨삭

회사 HR팀에서는 서류통과만 할 정도로 쓰면 된다.
맞춤법 틀리거나 프로젝트 설명을 읽고 무슨 소린지 알 수가 없는 수준만 아니면 패쓰
어차피 세부 검토는 개발팀에서 하는데
사실 여기 통과하는게 힘들다

  • 프로젝트 이름
  • 프로젝트 기간
  • 프로젝트 간략소개
  • 프로젝트에서 담당한 역할
  • 주요 기술스텍 목록
  • 내세울만한점이 있다면(개발시 신경썼던점, 기존 문제상황을 수정했던 부분 등)

헤드헌터가 유용한 경우는
구직자가 먼저 컨텍하는게 아닌 그 반대의 경우다
블로그나 깃헙을 보고 스카웃 제의를 하는 경우
요즘 그런식으로 이직했다는 소식을 간혹 듣긴한다
링크드인도 있겠지만 국내에서는 이거 잘 꾸며놓는 개발자 본 적이 없어서

정 도움이 필요한 경우

페이스북 개발자 모임같은데서 취업스터디 모집하는게 낫다
인맥도 생기고 운좋으면 도움의 손길이 있을수도??

헤드헌터는 여러분 한명한명에게 큰 공을 들이지 않고 관심도 없다
그리고 여러분이 뭘 했는지 제대로 이해하지 못하고 뭐가 중요한지 모른다
개발자 스터디에서 자기가 한 프로젝트에 대해 자세히 설명을 해 주고
함께 요약을 해 보면 훨씬 도움이 될 듯?

헤드헌터가 도움이 되는 경우??

간혹 비밀스럽게 채용이 이뤄지는 경우 공개적으로 이력서를 받지 않는 회사도 있긴 있다…
외국회사나 신규산업진출 등등의 경우..

하지만 보통은 대형 채용사이트와 회사 홈페이지에 함께 올라와 있다.
회사 입장에서도 직접 지원하는걸 더 좋아한다.
결국엔 연봉협상에서도 유리하다는 점

  • 사람인 : 괜찮은 좆소 많음 무난
  • 원티드 : 꽤 트렌디한 채용 서비스.. 사이트는 구린데 왠지 이미지가
  • 잡코리아 : 개인적으로 비선호인데
  • 로켓펀치 : 스타트업 채용
  • 프로그래머스 : 괜찮은 좆소 많음 무난… 탑프로그래머스는 별 도움안됨, 코딩테스트는 쓸만함
  • 인쿠르트 : 개발자는 잘 없지 않나
  • Okky : 구인구직 페이지.. 프리랜서 채용이 많다

남이 나보다 잘 해주지 못한다.

다 직접 해야된다

Querydsl crash – lombok plugin

plugin: 'org.jetbrains.kotlin.plugin.lombok

롬복 x 코틀린 오류

롬복과 코틀린을 함께 쓰려고 하면 오류가 많이 발생한다

컴파일타임에 진행되는 일의 순서 때문에 문제가 발생해서 매우 처리하기 힘들다
lombok, kapt, querydsl, protocol buffer, kotlin

이런저런것들이 컴파일타임에 순서대로 돌아가는데
이 오픈소스들이 애초에 이렇게 같이 쓰는 환경을 고려하고 만든게 아닌지라…
자바에서 코틀린 라이브러리를 쓰는 것 조차 쓸 수는 있는정도니까…
꼭 같이 써야겠다면 그레이들에서 모듈을 분리해서 다른 라이브러리를 쓰듯이 만들어 놔야한다
같은 프로젝트에서 같은모듈에서는 그냥 포기하자

lombok

> Task :server:core:compileKotlin
w: Lombok Kotlin compiler plugin is an experimental feature. See: https://kotlinlang.org/docs/components-stability.html.

Lombok Kotlin compiler plugin is an experimental feature. See: https://kotlinlang.org/docs/components-stability.html.

compileKotlin

java.lang.IllegalStateException: Error during writing proto for descriptor: @javax.annotation.Generated public open class QAdminEntity : com.querydsl.core.types.dsl.EntityPathBase<(kr.steppay.account.domain.model.actor.AdminEntity..kr.steppay.account.domain.model.actor.AdminEntity?)> defined in kr.steppay.account.domain.model.actor in file QAdminEntity.java
Source file: /Users/archmagece/work/steppay/account-service/server/domain/build/generated/source/kapt/main/kr/steppay/account/domain/model/actor/QAdminEntity.java
	at org.jetbrains.kotlin.incremental.JavaClassesTrackerImplKt.convertToProto(JavaClassesTrackerImpl.kt:90)
	at org.jetbrains.kotlin.incremental.JavaClassesTrackerImpl$onCompletedAnalysis$2.invoke(JavaClassesTrackerImpl.kt:68)
	at org.jetbrains.kotlin.incremental.JavaClassesTrackerImpl$onCompletedAnalysis$2.invoke(JavaClassesTrackerImpl.kt:67)
	at org.jetbrains.kotlin.util.PerformanceCounter.time(PerformanceCounter.kt:101)
	at org.jetbrains.kotlin.incremental.JavaClassesTrackerImpl.onCompletedAnalysis(JavaClassesTrackerImpl.kt:67)
	at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$invokeExtensionsOnAnalysisComplete(TopDownAnalyzerFacadeForJVM.kt:110)
	at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:129)
	at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:86)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:540)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:531)
	at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:113)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:531)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:188)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli$default(KotlinToJVMBytecodeCompiler.kt:154)
	at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:169)
	at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:52)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:90)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:44)
	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:98)
	at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:386)
	at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:110)
	at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileIncrementally(IncrementalCompilerRunner.kt:303)
	at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileImpl$rebuild(IncrementalCompilerRunner.kt:99)
	at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileImpl(IncrementalCompilerRunner.kt:124)
	at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:74)
	at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:607)
	at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:96)
	at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1659)
	at jdk.internal.reflect.GeneratedMethodAccessor105.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:359)
	at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
	at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:562)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:796)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:677)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:676)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.NullPointerException
	at org.jetbrains.kotlin.lombok.processor.RequiredArgsConstructorProcessor.isFieldRequired(RequiredArgsConstructorProcessor.kt:27)
	at org.jetbrains.kotlin.lombok.processor.RequiredArgsConstructorProcessor.getPropertiesForParameters(RequiredArgsConstructorProcessor.kt:24)
	at org.jetbrains.kotlin.lombok.processor.AbstractConstructorProcessor.contribute(AbstractConstructorProcessor.kt:19)
	at org.jetbrains.kotlin.lombok.LombokSyntheticJavaPartsProvider.computeSyntheticParts(LombokSyntheticJavaPartsProvider.kt:80)
	at org.jetbrains.kotlin.lombok.LombokSyntheticJavaPartsProvider.getSyntheticParts(LombokSyntheticJavaPartsProvider.kt:74)
	at org.jetbrains.kotlin.lombok.LombokSyntheticJavaPartsProvider.generateConstructors(LombokSyntheticJavaPartsProvider.kt:63)
	at org.jetbrains.kotlin.resolve.jvm.CompositeSyntheticJavaPartsProvider.generateConstructors(SyntheticJavaPartsProvider.kt:59)
	at org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassMemberScope$constructors$1.invoke(LazyJavaClassMemberScope.kt:102)
	at org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassMemberScope$constructors$1.invoke(LazyJavaClassMemberScope.kt:84)
	at org.jetbrains.kotlin.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)
	at org.jetbrains.kotlin.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527)
	at org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor.getConstructors(LazyJavaClassDescriptor.kt:146)
	at org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor.getConstructors(LazyJavaClassDescriptor.kt:45)
	at org.jetbrains.kotlin.serialization.DescriptorSerializer.classProto(DescriptorSerializer.kt:115)
	at org.jetbrains.kotlin.incremental.JavaClassesTrackerImplKt.convertToProto(JavaClassesTrackerImpl.kt:88)
	... 43 more


[도서] 소프트웨어 장인

그냥 개발수필에 가깝다
코딩호러의 어쩌고 했던책이 더 재밌었던듯

이 책에서 뭔가 내용이 많이 나오긴 하는데
맞는말이긴 한데 그냥 맞는말뿐이라서 별로 뭔소린지 기억에 남지 않는다

마틴파울러나 GoF같은 유명한 책은 많이 읽은 사람인 것 같다
개발방법론이나 조직에 대해 많이 생각해봤던
10~20년쯤 소프트웨어 개발을 했던 프로그래머
대부분 그정도 근방의 이력을 가진 사람이면 해 봤을법한 생각들

아예 초년생이라면
감명받을 수도 있겠고
뭔소린가 싶을수도 있겠는데
한번 훑어보는게 도움이 되려나

이 책의 태그를 자기계발서로 넣은건…
기술서적이 아니기 때문.

네이버 클라우드 사용후기

네이버 클라우드는
중소 벤처기업에 요금지원을 1~2년씩 해주면서
사용자를 모으고 있는 것 같다

IaC

먼저… 사용하기 매우 싫었다

왜냐면 코드화가 불가능한 인프라라서
https://github.com/NaverCloudPlatform/terraform-provider-ncloud
7개월 째 업데이트가 안 되고 있다
API지원이 미약하거나 테라폼의 중요성을 모르거나 둘 중 하나겠지…
API를 이용해서 직접 코드화를 할까도 생각 해 봤지만…
AWS, GCP, Azure, DOcean, Heroku …. 선택지가 이렇게 많은데 그렇게까지???

비용

그리고 가격만 생각할 것 같으면 통큰아이 서버 쓰는게 낫지 않을까
IDC에 렉 하나 임대해서 서버 들여놓던가

AWS에서 비용 최적화 해서 사용하면 가격이 비슷할 것 같기도 하다
AWS는 BestPractice도 많고 Terraform코드화가 쉬워서

코드화가 가능하면 안쓰는 인프라를 그 때 그 때 껐다가 다시 켜고 재설정이 가능해서

설치편의성

ElasticSearch를 설치했는데
ManagerNode가 두개인데
별개로 접할수가 없어서 찾다보니
LoadBalancer를 설치해야한다고??? 18000원이라고????

가입 편의성

금융클라우드는 Console에 VPN없이 접속이 안된다. 경고는 따로 없고 타임아웃

VPN을 통해야 접속이 가능한데 동시접속이 안된다

VPN을 만들려면 SubAccount가 필요하다
2차인증이 필수라길래 구글 OTP를 등록했더니
VPN을 등록하려면 이메일 인증을 해야한다고 한다
이메일 안오는데?????
스팸인가?? 네이버 메일로만 전송을 해주나???
SubAccount를 다시 생성해볼까??
네이버 서버 병신이네!!! 라고 생각하다가 문득
아니!!
구글OTP를 등록하고 나면 이메일 인증을 할 수 없다.
설마했지만 맞았다.
병신은 서버가 아니라 소프트웨어였다
클라우드도 기획자가 있나? 기획자가 보내준거 리뷰 후에 변경안하고 바로 개발 해 버나?
개발자가 이따위로 했을리가…
이따위로 할 수는 있긴한데 그대로 놔뒀을리가…
구글OTP를 안되는거 지웠으면 지웠지…

~

쓰고 나니까 좋은 소리가 하나도 없네
잘좀 하시라구요

  • 점점 나아지겠지만 아직은 아니다
  • 네이버클라우드 직원들 고생좀 하겠다