Skip to content

Commit

Permalink
이미지 경로 아직 baseurl 반영 안 된 것 찾아서 정정
Browse files Browse the repository at this point in the history
  • Loading branch information
starrybleu committed Nov 8, 2024
1 parent 672b34f commit 2cd48fd
Show file tree
Hide file tree
Showing 21 changed files with 68 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ tags:

지금 우리가 배포하려는 서버는 다음과 같은 구조를 가지고 있다고 가정합니다.

[![서버구조](/images/8yVXHQuTvF.png)](https://blog.dramancompany.com/wp-content/uploads/2015/09/스크린샷-2015-09-25-14.42.22.png)
[![서버구조]({{ site.baseurl }}/images/8yVXHQuTvF.png)](https://blog.dramancompany.com/wp-content/uploads/2015/09/스크린샷-2015-09-25-14.42.22.png)

이와같은 구조에서 배포를 할 경우 일단 ELB 구성이 되어 있으므로 다음과 같은 순서로 무중단 배포는 가능합니다.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,13 @@ MPA로 B/O 제품들을 개발하던 Jaden은 시스템 속도 개선, 생산성

턴제 방식의 페어 방식의 페어 프로그래밍을 진행하던 중, 둘 다 아무래도 처음 정했던 1시간이 애매한 시간이라는 생각이 들었습니다. 1시간이 집중도가 한참 높아질 때여서 1시간 마다 턴 변경을 자주 놓치게 되었고 그러다 보니 키보드를 잡고 있지 않은 사람의 집중도가 약간 떨어지는 경향이 있었습니다. 그래서 방식을 동시제로 변경했습니다. 다음 사진을 보시죠.

[![pair_programming](/images/lksLiI09Bl.jpg)](https://blog.dramancompany.com/wp-content/uploads/2015/11/pair_programming.jpg)
[![pair_programming]({{ site.baseurl }}/images/lksLiI09Bl.jpg)](https://blog.dramancompany.com/wp-content/uploads/2015/11/pair_programming.jpg)



사진 왼쪽의 노트북에서는 설계와 관련된 내용을 작성, 가운데의 모니터로 코드를 공유, 오른쪽의 노트북으로는 결과 실행을 합니다. 가운데의 키보드와 트랙패드는 우측 노트북과 연결하여 Tom이 사용하고 Jaden은 우측의 노트북으로 코드를 작성합니다.[](http://deopard.cafe24.com/wp-content/uploads/2015/10/pair_programming.jpg)

[![slack-for-ios-upload-1]({{ site.baseurl }}/images/IabfBFuDLV.jpg)](https://blog.dramancompany.com/wp-content/uploads/2015/11/Slack-for-iOS-Upload-1.jpg) [![slack-for-ios-upload-2](/images/PDFZ57K6U8.jpg)](https://blog.dramancompany.com/wp-content/uploads/2015/11/Slack-for-iOS-Upload-2.jpg)
[![slack-for-ios-upload-1]({{ site.baseurl }}/images/IabfBFuDLV.jpg)](https://blog.dramancompany.com/wp-content/uploads/2015/11/Slack-for-iOS-Upload-1.jpg) [![slack-for-ios-upload-2]({{ site.baseurl }}/images/PDFZ57K6U8.jpg)](https://blog.dramancompany.com/wp-content/uploads/2015/11/Slack-for-iOS-Upload-2.jpg)

_<혼자가 아닌 둘이니 개발 설계에 대해 토의도 하면서 화이트보드에 적을 수도 있습니다>_

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ date: "2015-11-25"

리멤버 또한 구글이 준 유예기간 동안 프리뷰 이미지 및 오픈 테스트 랩 등을 활용해 새로운 안드로이드 M버전에 대응하였습니다. 그 과정을 공유드리고자 합니다.

<caption id="attachment\_267" align="aligncenter" width="300">[![pv9AcTqS-gotB5ply6js6SgqwcMrXcvbZlicenbfWh5Q-iW7cf6RrGM-TR7dSM0Z2BbVGA=s2048](/images/6O5FqHXNU1.png)](https://blog.dramancompany.com/wp-content/uploads/2015/11/pv9AcTqS-gotB5ply6js6SgqwcMrXcvbZlicenbfWh5Q-iW7cf6RrGM-TR7dSM0Z2BbVGAs2048.png) 안드로이드 6.0 마시맬로우 마스코트. 필자는 이 그림과 똑같은 피규어가 있습니다.</caption>
<caption id="attachment\_267" align="aligncenter" width="300">[![pv9AcTqS-gotB5ply6js6SgqwcMrXcvbZlicenbfWh5Q-iW7cf6RrGM-TR7dSM0Z2BbVGA=s2048]({{ site.baseurl }}/images/6O5FqHXNU1.png)](https://blog.dramancompany.com/wp-content/uploads/2015/11/pv9AcTqS-gotB5ply6js6SgqwcMrXcvbZlicenbfWh5Q-iW7cf6RrGM-TR7dSM0Z2BbVGAs2048.png) 안드로이드 6.0 마시맬로우 마스코트. 필자는 이 그림과 똑같은 피규어가 있습니다.</caption>

## **M버전, 무엇을 대응해야 하나?**

Expand Down Expand Up @@ -80,7 +80,7 @@ M버전의 대응의 90%는 권한모델을 넣는 것 이였습니다. 그만

[http://developer.android.com/intl/ko/reference/android/Manifest.permission\_group.html](http://developer.android.com/intl/ko/reference/android/Manifest.permission_group.html)

<caption id="attachment\_250" align="aligncenter" width="211">[![6.0 부터는 사용자가 설정창에서 권한그룹 단위로 허용/거부를 명시적으로 할 수 있습니다.](/images/j4mU7284G3.jpeg)](https://blog.dramancompany.com/wp-content/uploads/2015/11/권한그룹-설정창.jpeg) M버전 부터는 사용자가 설정창에서 권한그룹 단위로 허용/거부를 명시적으로 할 수 있습니다.</caption>
<caption id="attachment\_250" align="aligncenter" width="211">[![6.0 부터는 사용자가 설정창에서 권한그룹 단위로 허용/거부를 명시적으로 할 수 있습니다.]({{ site.baseurl }}/images/j4mU7284G3.jpeg)](https://blog.dramancompany.com/wp-content/uploads/2015/11/권한그룹-설정창.jpeg) M버전 부터는 사용자가 설정창에서 권한그룹 단위로 허용/거부를 명시적으로 할 수 있습니다.</caption>

### 사용자에게 필요한 권한을 요청하자

Expand Down Expand Up @@ -275,7 +275,7 @@ public static void requestOverlayPermission(Activity activity) {

설정창으로 넘어가게 하는 것은 쉽지만, 사용자에게 낯선 권한을 허용받기 위해서는 왜 이 권한이 필요한지를 잘 설명하는 것이 중요하겠습니다.

<caption id="attachment\_251" align="aligncenter" width="226">[![system_window_alter는 다른 권한들과 다르게 '다른 앱 위에 그리기' 설정창에서 직접 허용받아야 합니다.](/images/ii392AL6Dc.jpeg)](https://blog.dramancompany.com/wp-content/uploads/2015/11/다른앱-위에-그리기.jpeg) system\_window\_alert는 다른 권한들과 다르게 '다른 앱 위에 그리기' 설정창에서 직접 허용받아야 합니다.</caption>
<caption id="attachment\_251" align="aligncenter" width="226">[![system_window_alter는 다른 권한들과 다르게 '다른 앱 위에 그리기' 설정창에서 직접 허용받아야 합니다.]({{ site.baseurl }}/images/ii392AL6Dc.jpeg)](https://blog.dramancompany.com/wp-content/uploads/2015/11/다른앱-위에-그리기.jpeg) system\_window\_alert는 다른 권한들과 다르게 '다른 앱 위에 그리기' 설정창에서 직접 허용받아야 합니다.</caption>

'다른 앱 위에 그리기' 권한을 사용할 수 있는지 여부는 [Settings.canDrawOverlays()](http://developer.android.com/intl/ko/reference/android/provider/Settings.html#canDrawOverlays(android.content.Context))를 이용해 알 수 있습니다. 하지만 아쉽게도 system\_window\_alert는 다른 권한들처럼 [onRequestPermissionsResult()](http://developer.android.com/intl/ko/reference/android/support/v4/app/ActivityCompat.OnRequestPermissionsResultCallback.html#onRequestPermissionsResult(int, java.lang.String[], int[]))으로 사용자가 권한을 허용/거부한 결과값을 알수 없습니다. 그래서 저희는 위 코드에서도 보이듯이 [startActivityForResult()](http://developer.android.com/intl/ko/reference/android/app/Activity.html#startActivityForResult(android.content.Intent, int))로 요청하여 [onActivityResult()](http://developer.android.com/intl/ko/reference/android/app/Activity.html#onActivityResult(int, int, android.content.Intent))에서 결과값을 받아 작업을 실행하였습니다.

Expand Down Expand Up @@ -308,7 +308,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {

### **최초의 마시맬로우 기기, 넥서스 5x만의 이슈**

<caption id="attachment\_268" align="aligncenter" width="287">[![image00](/images/EiKh8CHhDy.png)](https://blog.dramancompany.com/wp-content/uploads/2015/11/image00.png) 넥서스 5x. 필자가 사용하고 있는 폰 입니다.</caption>
<caption id="attachment\_268" align="aligncenter" width="287">[![image00]({{ site.baseurl }}/images/EiKh8CHhDy.png)](https://blog.dramancompany.com/wp-content/uploads/2015/11/image00.png) 넥서스 5x. 필자가 사용하고 있는 폰 입니다.</caption>

### 1\. 전화번호가 국제번호로 변경되어서 옵니다

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ date: "2015-12-04"

# **Electron**

# [![Electron](/images/E62En13yxt.png)](https://blog.dramancompany.com/wp-content/uploads/2015/11/스크린샷-2015-11-16-오후-4.42.42.png)
# [![Electron]({{ site.baseurl }}/images/E62En13yxt.png)](https://blog.dramancompany.com/wp-content/uploads/2015/11/스크린샷-2015-11-16-오후-4.42.42.png)

[Electron](http://electron.atom.io/)[Chromium](https://www.chromium.org/)[Node.js](https://nodejs.org)를 이용하여 데스크톱 앱을 HTML, CSS, JavaScript로 쉽게 만들 수 있게 해주는 프레임워크입니다. GitHub에서 Atom editor를 만들기 위해서 시작된 프로젝트로 원래 이름은 Atom Shell이었다가 Electon으로 이름이 바뀌었습니다. 앞서 말씀드린 것과 같이 Electon을 이용하면 쉽게 cross-platform 앱을 개발할 수 있습니다.  또한 웹 개발자분들도 익숙한 언어와 코드를 재사용하여 쉽게 데스크톱 앱을 개발할 수 있습니다.

Expand All @@ -26,15 +26,15 @@ date: "2015-12-04"

#### Electron으로 만들어진 앱들

[![스크린샷 2015-11-16 오후 4.48.30](/images/vzNrP9v0w8.png)](https://blog.dramancompany.com/wp-content/uploads/2015/11/스크린샷-2015-11-16-오후-4.48.30.png)
[![스크린샷 2015-11-16 오후 4.48.30]({{ site.baseurl }}/images/vzNrP9v0w8.png)](https://blog.dramancompany.com/wp-content/uploads/2015/11/스크린샷-2015-11-16-오후-4.48.30.png)

[여기](http://electron.atom.io/#built-on-electron)를 확인해보시면 Electron을 이용하여 만들어진 앱들이 나와 있습니다. 아마 제일 앞의 세 개가 낯익으실 텐데, GitHub의 text editor인 Atom, Slack Technologies의 협업 메신저인 Slack, MS의 Visual Studio Code가 있습니다. 세 가지 앱 모두 제가 사용을 하는 앱이고(Atom과 Slack은 컴퓨터가 켜져 있는 시간의 99%) Mac과 Windows 모두 그 퀄리티에 만족을 하면서 사용하고 있었기 때문에 Electon으로도 충분히 좋은 앱을 만들 수 있다고 판단했습니다.

#### Squirrel 인스톨러



[![5743792](/images/6YWIILjtjG.png)](https://blog.dramancompany.com/wp-content/uploads/2015/11/5743792.png)
[![5743792]({{ site.baseurl }}/images/6YWIILjtjG.png)](https://blog.dramancompany.com/wp-content/uploads/2015/11/5743792.png)

Slack이나 Atom을 Windows 환경에서 인스톨러를 실행할 경우 기존의 '다음', '다음' 그리고 '다음'의 과정 없이 로딩 이미지가 잠깐 뜨다가 바로 앱이 실행됩니다. 그리고 업데이트도 Chrome처럼 언제 일어났는지도 눈치챌 수 없을 정도로 자연스럽게 일어납니다. 이는 [Squirrel 인스톨러](https://github.com/Squirrel)가 자동으로 해주는 부분입니다. 꼭 Squirrel 인스톨러를 사용해야 하는 것은 아니지만, Slack이나 Atom 같은 경우 Squirrel 인스톨러를 사용하여 만들었고 이들이 주장하는 "인스톨과 업데이트는 간단해야 한다"가 제일 만족스러운 부분이었습니다. 정말 인스톨러나 업데이터를 만드는데 신경을 거의 쓰지 않아도 됩니다(한번 이해만 한다면..).

Expand All @@ -48,7 +48,7 @@ Slack이나 Atom을 Windows 환경에서 인스톨러를 실행할 경우 기존

공식 홈페이지에 나와 있는 [튜토리얼](https://github.com/atom/electron/tree/master/docs-translations/ko-KR)이 잘 되어있다고 생각하기 때문에 이 글에서는 개발 방법에 대한 얘기는 별도로 다루지 않도록 하겠습니다. 그보다 큰 그림을 이해하기 위한 구조를 소개해드리겠습니다.

[![스크린샷 2015-11-16 오후 4.17.55](/images/yO1l9h0trE.png)](https://blog.dramancompany.com/wp-content/uploads/2015/11/스크린샷-2015-11-16-오후-4.17.55.png) 크게 두 가지 프로세스가 존재합니다. Renderer 프로세스는 Chromium 기반으로 HTML, CSS, JavaScript를 이용하여 웹 페이지를 만들듯 view를 구성합니다. Main 프로세스는 Node.js 기반으로 일반적인 Node application이라고 생각하시면 되겠습니다. 모든 node 모듈들을 가져다 쓸 수 있습니다. 그리고 각 프로세스마다 electron 앱에 접근해서 사용할 수 있게 만든 electon에서 제공되는 API들이 담긴 모듈들이 있습니다. 그리고 두 process 사이를 통신할 수 있게 해주는 ipc와 remote module이 존재합니다. 웹 개발자는 원래 front-end를 개발하던 것과 같이 Renderer 프로세스 쪽을 개발하고 back-end를 Node.js로 개발하듯 Main 프로세스 쪽을 개발하면 됩니다. 그때그때 필요한 Electron의 API만 찾아 쓰면 기존의 웹 개발하던 것과 차이가 거의 없습니다.
[![스크린샷 2015-11-16 오후 4.17.55]({{ site.baseurl }}/images/yO1l9h0trE.png)](https://blog.dramancompany.com/wp-content/uploads/2015/11/스크린샷-2015-11-16-오후-4.17.55.png) 크게 두 가지 프로세스가 존재합니다. Renderer 프로세스는 Chromium 기반으로 HTML, CSS, JavaScript를 이용하여 웹 페이지를 만들듯 view를 구성합니다. Main 프로세스는 Node.js 기반으로 일반적인 Node application이라고 생각하시면 되겠습니다. 모든 node 모듈들을 가져다 쓸 수 있습니다. 그리고 각 프로세스마다 electron 앱에 접근해서 사용할 수 있게 만든 electon에서 제공되는 API들이 담긴 모듈들이 있습니다. 그리고 두 process 사이를 통신할 수 있게 해주는 ipc와 remote module이 존재합니다. 웹 개발자는 원래 front-end를 개발하던 것과 같이 Renderer 프로세스 쪽을 개발하고 back-end를 Node.js로 개발하듯 Main 프로세스 쪽을 개발하면 됩니다. 그때그때 필요한 Electron의 API만 찾아 쓰면 기존의 웹 개발하던 것과 차이가 거의 없습니다.



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,43 +34,43 @@ APM하면 가장 먼저 [Jennifer](http://www.jennifersoft.com)같은 솔루션

APM의 아주 기본적인 기능입니다. NewRelic은 아래 그림과 같이 각 컴포넌트/시스템별로 쪼개서 트랜잭션 수행 시 걸린 시간을 측정합니다.

[![transaction_response_time](/images/u0U9Ihvc9a.png)](https://blog.dramancompany.com/wp-content/uploads/2015/12/transaction_response_time.png)
[![transaction_response_time]({{ site.baseurl }}/images/u0U9Ihvc9a.png)](https://blog.dramancompany.com/wp-content/uploads/2015/12/transaction_response_time.png)

리멤버 서버 애플리케이션의 경우 모니터링 대상이 되는 컴포넌트들은 아래와 같습니다.

[![transaction_components](/images/YY6nOuPBRd.png)](https://blog.dramancompany.com/wp-content/uploads/2015/12/transaction_components.png)
[![transaction_components]({{ site.baseurl }}/images/YY6nOuPBRd.png)](https://blog.dramancompany.com/wp-content/uploads/2015/12/transaction_components.png)

- Middleware: Rails에서 HTTP 요청을 parsing하여 해당 Controller로 라우팅하는 등 Application 코드가 아닌 Rails 자체에서 요청 처리에 걸린 시간
- Ruby: 개발자가 개발한 애플리케이션에서 걸린 시간
- ActiveRecord: ActiveRecord 모델에서 데이터베이스에 쿼리를 전달하고 응답을 받기까지 걸린 시간
- Redis: Redis에 접속하여 명령을 전달하고 응답을 받기까지 걸린 시간
- Web external: 구글, 네이버, 페이스북 등 외부 API를 호출하여 응답을 받기까지 걸린 시간

위 그림에서는 오후 2:30분부터 3시까지 ActiveRecord에서 시간이 오래 걸린 것을 볼 수 있습니다. 따라서 이 때 DB에 뭔가 이슈가 있었는지 확인을 해볼 필요가 있습니다.[![system-health](/images/US5qJ1kryg.png)](https://blog.dramancompany.com/wp-content/uploads/2015/12/system-health.png)
위 그림에서는 오후 2:30분부터 3시까지 ActiveRecord에서 시간이 오래 걸린 것을 볼 수 있습니다. 따라서 이 때 DB에 뭔가 이슈가 있었는지 확인을 해볼 필요가 있습니다.[![system-health]({{ site.baseurl }}/images/US5qJ1kryg.png)](https://blog.dramancompany.com/wp-content/uploads/2015/12/system-health.png)

Apdex는 시스템의 전반적인 상태를 나타냅니다. 평균 응답 시간의 threshold(App Server 기본값은 0.5초, Browser는 7초)를 설정하여 특정 시간 동안 이 값을 만족시키지 못하면 alert를 발생시키게 됩니다. Apdex는 순수하게 서버에서 요청을 처리한 시간과 사용자의 브라우저 입장에서 걸린 시간 두 가지를 나누어 보여줍니다.

Throughput은 분당 유입되는 요청의 수를 나타냅니다. 따라서, 서버에 어떤 이슈가 발생했을 때 순전히 요청량이 많아져서인지, 아니면 요청량은 변화가 없는데 서버 내부의 문제 때문인지 쉽게 파악할 수 있습니다.

#### **B. Transaction Traces**

[![transaction_traces](/images/YOR3GW3tZW.png)](https://blog.dramancompany.com/wp-content/uploads/2015/12/transaction_traces.png)
[![transaction_traces]({{ site.baseurl }}/images/YOR3GW3tZW.png)](https://blog.dramancompany.com/wp-content/uploads/2015/12/transaction_traces.png)

이것도 APM에서 제공하는 기본 기능입니다. 각 트랜잭션에서 메소드별로 처리 시간을 쪼개 보여줍니다. 따라서 어느 메소드에서 시간이 가장 오래 걸렸는지 쉽게 파악할 수 있고 이를 토대로 애플리케이션 혹은 DB 쿼리 튜닝을 할 수 있습니다. 아마 많은 분들이 익숙하신 기능이라 생각됩니다.

#### **C. Error Traces**

에러 추적을 위한 강력한 기능입니다. 아래와 같이 애플리케이션 내에서 예외가 발생하면 트랜잭션의 여러 가지 속성(요청한 사용자  ID, 요청 시간 등)과 함께 스택 트레이스를 보여줍니다.

[![error_traces](/images/IDK4LAfzeU.png)](https://blog.dramancompany.com/wp-content/uploads/2015/12/error_traces.png)
[![error_traces]({{ site.baseurl }}/images/IDK4LAfzeU.png)](https://blog.dramancompany.com/wp-content/uploads/2015/12/error_traces.png)

위 에러는 리멤버 앱에서 저장한 명함을 구글 주소록에 동기화할 때 발생한 에러입니다. 구글 주소록 API는 단시간에 너무 많은 요청이 일어나면 위와 같이 UserRateLimitExceeded와 같은 에러를 리턴하는데 이는 개발이나 테스트 환경에서 일어나기 무척 힘든 에러입니다. APM이 없었다면 아마 발견할 수 없었을 것이고 고객 클레임이 들어왔을 것이 분명합니다. 그러나 꾸준한 모니터링을 통해 위 에러를 발견하고 적절히 수정하여 고객 만족도를 더욱 높일 수 있었습니다.

#### **D. Others**

NewRelic은 제 경험상 기능에 대한 업데이트가 빠른 편입니다. 얼마 전에는 NewRelic Insight 모듈(애플리케이션에서 발생하는 이벤트를 분석해주는 도구)을 이용하여 에러를 분석해주는 Error analytics 기능을 추가하였습니다.

[![error_analytics](/images/57cun9RtTZ.png)](https://blog.dramancompany.com/wp-content/uploads/2015/12/error_analytics.png)
[![error_analytics]({{ site.baseurl }}/images/57cun9RtTZ.png)](https://blog.dramancompany.com/wp-content/uploads/2015/12/error_analytics.png)

물론 단점도 있습니다. 빠르게 업데이트되다 보니 버그도 간혹 생깁니다. 실제로 위의 Error analytics가 추가되고 나서, Background job에서 발생하는 에러가 NewRelic에 잡히지 않는 버그가 있었습니다. 하지만 그에 대한 대응도 빠르게 해주는 편입니다. (버그 리포팅을 했더니 친절하게 응대해주고, 1주일만에 버그 fix한 에이전트를 릴리즈해주었습니다. 이 정도면 괜찮지 않은가요?^^)

Expand Down
Loading

0 comments on commit 2cd48fd

Please sign in to comment.