API 작성 중 

 

26번까지의 반복 작업(반복문)-- 각 작업마다 조금씩 다름 --

 

을 통해서 구한 정보를 데이터 베이스에 토큰단위로 삽입을 하는 작업인데,

 

카운트를 해보니 계속 0~9까지 작업 중 10번에서 계속 서버가 멈추는 이슈가 발생했습니다.

 

처음에는 10번 작업에 문제가 있는 줄 알고, 확인을 해봤는데 딱히 문제를 발견하지 못해서

 

10~26번 까지 돌려 보니 10,11,12.........20에서 멈추는 것이였습니다.

 

자바스크립트에 아직 그리 익숙치 않아 여러 문제 발생가능 지점을 찾아봤는데, 잘 해결이 안되었는데

 

문제는 connection.release()를 안해주고 있었습니다......바보......

 

const connection= await pool.getConnection(async (conn) => conn); 을 해줬으면 

 

밑에서 connection.release()를 반드시 해줘야 한다..

 

반납하지 않으면 connection leak현상이 발생할 수 있다.

 

릴리즈를 해줘야 이 커넥션은 pool로 돌아가서 다른 주체가 사용할 수 있도록 할 수 있다.

예전에 php를 스크립트 언어로 하여 서버를 구성했던 프로젝트가 있는데

 

 

이번에는 자바스크립트 런타임인 노드 js를 이용하여 서버를 구축하여 작업을 하고 있는데,

 

 

서버 구성의 큰 축은 같지만, 이게 혼자 알아가면서 작성하려고 하니 오류에 많이 부딛히네요

 

 

작동이 안하는 에러는 아니지만 오늘은 실행시 Unhandled promise rejection이 콘솔에 계속 떠서

 

 

알아보니 async,await에서 핸들링 처리를 하지 않은 부분이 있으면 이러한 warnig이 뜬다고 하네요.

 

 

async-await를 걸어준 곳은 try로 감싸주고 catch로 에러핸들링을 처리해줘야 한다는 것.........!!!!

 

 

async-await는 비동기 처리코드 작성이 익숙하지 않은 저 같은 사람에게 도움을 주는...... 아주 소중한....

 

 

바쁜 시기가 좀 지나가고 시간이 좀 나면 자바스크립트를 꼼꼼하게 공부해보고 싶네요......!

Python-shell 이용하여, Nodejs에서 파이썬 스크립트 실행시키기

 

최근노드js를 이용하여 어플을 제작 중에 있습니다.

 

만들고자 하는 기능 중 시간에 민감한 기능이 있는데, 파이썬의 api를 이용해서 구현한 것을

 

nodejs에서 실행시키고, 결과를 받아와야 할 일이 있어서, 찾아보고 진행하였습니다.

 

찾아본 결과, child-process 이용, python-shell 이용 등의 방법들이 있었는데, 비교적 간단한 파이썬 스크립트를

 

실행하는 작업이였기 때문에 저는 python-shell 을 이용하여 진행하였습니다.

 

매우 간단한 작업 같으나, 다른 블로그의 게시글 중 오래된 글들도 있어, 오류가 좀 났었습니다.

 

버전에 따른 차이도 조금 있을거라 생각하는데, 실행시킨 코드는 다음과 같습니다.

( 우분투 버전 18.04 에서 진행하였고, python-shell, 파이썬 설치 및 추가로 사용할 모듈들은 설치를 따로 해주셔야 

원하는 결과를 받으실 수 있을겁니다....!)

 

 도 설치해야 했던 것으로 기억하고, 제 코드에는 시간을 측정하는 코드가 추가로 들어가있습니다.

 

현재 상황에서는 파이썬 스크립트로 전달할 값이 없었으므로, 추석처리 했으나 포함시켜 실행도 가능합니다.

 

파이썬에서는 sys.argv 와 같은식으로 값을 사용가능합니다.

 

저는 index.js ( app.js 인 분들도 많으시겠죠 )

 

와 같은 폴더내에 파이썬 스크립트를 넣어놓았으므로 scriptPath: 는 따로 설정하지 않았습니다.

 

결과는 파이썬에서 print한 결과를 받아옵니다.

'Web & App > Nodejs' 카테고리의 다른 글

(21.05.26) connection.release() 꼭  (0) 2021.05.27
(21.05.23) async-await 에러 핸들링  (0) 2021.05.24

요즘 다시 팀원들과의 프로젝트를 위해 서버를 구축하여 사용하고 있습니다.

 

AWS EC2 프리티어를 이용하여 서버를 구축해서 사용하고 있는데,

 

프리티어 이고 아이디가 아직 1년도 지나지 않았는데, 0.27 달러 정도 아주 조금씩이라도 과금이 쌓이고 있더라고요.....!

 

그래서 Billing을 들어가서 상세 내역을 보았는데, 일단 대부분이 Elastic IP (탄력적 IP허용) 에 과금이 조금씩 되고 있더라구요...!

 

탄력적 IP기능이란, AWS EC2의 경우 IP를 동적할당 함으로써 인스턴스를 중지 하고 다시 실행할 경우

 

IP주소가 바뀌게 되는데, 이럴때 인스턴스를 껐다 켜도 IP주소를 고정으로 사용하고 싶을 때 사용하는 기능입니다.

 

프리티어는 한달에 750시간까지 무료인 것으로 알고 있고, 인스턴스 하나만 돌릴경우 한달 내내 켜놓아도 과금이 되지 않는 시간입니다.

 

인스턴스를 여러 개 사용하거나 한다면, 과금을 조금 하거나, 인스턴스 사용량을 조절을 해주어야 겠지요....?

 

사용량을 조절하는 과정에서 탄력적IP는 꽤나 편리할 것으로 보이지만, 저는 일단 그쪽에서 과금이 조금 되길래

 

인스턴스가 아직 한개이고, 중지 시킬일도 별로 없어서 일단 탄력적 IP를 릴리스 했습니다.

 

RDS 쪽에서도 아주 조금 과금이 되던데 백업스토리지 쪽에서 빠져나가고 있네요..!

 

사실 지금까지 합쳐도 300원 수준이라... 하지만 찝찝하고 약간은 불안한 마음...ㅋㅋㅋㅋㅋㅋㅋㅋㅋ

 

 

1. FROM, JOIN

 

- 먼저 FROM ( 테이블 ) JOIN ( 테이블 ) 이 실행되어 데이터셋을 뽑아냅니다.

 

- Sub Query문 (서브쿼리)도 실행되며 임시 테이블이 생성될 수 있습니다.

 

 

 

2. WHERE

 

- 1에서 뽑아낸 데이터셋에서 WHERE 조건문에 기재된 제약조건 대로 이를 충족하는 행만 뽑아냅니다.

 

 

 

3. GROUP BY

 

- 2에서 뽑아낸 데이터셋에 대해서 그룹조건을 적용하여 그룹으로 묶어줍니다.

 

 

 

4. HAVING

 

- 그룹으로 묶여진 데이터셋에 대해서 HAVING 조건절을 만족하는 행만이 남습니다.

 

 

 

5. SELECT

 

- 4까지 완료된 데이터 셋에 대하여 SELECT문을 실행하여 원하는 칼럼을 설정합니다.

 

 

 

6. DINSTINCT

 

- DISTINCT를 사용할 경우 이 단계에서 중복되는 행은 제거 됩니다.

 

 

 

 

7. ORDER BY

 

- 지금까지 만들어진 데이터셋을 어떤식으로 정렬 할 것인지 정합니다(오름차순, 내림차순)

 

 

 

8. LIMIT / OFFSET

 

- 최종적으로 범위를 지정 (지정된 범위를 벗어나는 행을 제거) 합니다.

 

 

 

 

 

[출처]:

https://sqlbolt.com/lesson/select_queries_order_of_execution
jaimemin.tistory.com/1475?category=1060172

 

데이터베이스 쿼리 실행 순서

회사를 직접적으로 언급할 수는 없지만 데이터베이스 쿼리 실행 순서를 질문받은 적 있습니다. 코딩 테스트 난이도 정도의 쿼리 작성에는 어느 정도 자신이 있었지만 실행 순서는 한 번도 생각

jaimemin.tistory.com

 

SQLBolt - Learn SQL - SQL Lesson 12: Order of execution of a Query

Now that we have an idea of all the parts of a query, we can now talk about how they all fit together in the context of a complete query. Complete SELECT query SELECT DISTINCT column, AGG_FUNC(column_or_expression), … FROM mytable JOIN another_table ON m

sqlbolt.com

 

'Web & App > Mysql' 카테고리의 다른 글

Pagenation(페이징) [Offset-based, Cursor-based)  (0) 2020.10.17
mysql 외부 접속 허용  (0) 2020.08.17

1. JSON이란?

 

 

- 이름에서도 알 수 있지만 JavaScript의 객체를 정의하는 문법과 매우 유사한 형식을 따릅니다..

 

 

- 하지만 문법,프로토콜 등은 아니고 그저 텍스트 일 뿐......(데이터를 표시하는 방법)

 

 

- 일단 형식 자체가 이해하기가 매우 쉽다는 장점이 있습니다.

 

 

- 데이터를 전송하거나 저장을 할 때 많이 사용하는 형식 정도 라고 생각하면 될 것 같습니다.

 

 

 

 

 

2. JSON 특징

 

 

- JavaScript 함수를 통해 JSON형식의 파일을 JavaScript의 객체로 변환 할 수 있습니다.

  (JSON.parse("json텍스트") --> json을 자바스크립트 객체로)

  (JSON.stringify("자바스크립트 객체") --> 자바스크립트 객체를 json으로)

 

 

- 다양한 언어에서 json 데이터를 다룰 수 있는 라이브러리를 제공하고 있습니다.

 

 

- 서버와 클라이언트의 데이터 교류에 json형식이 많이 사용됩니다

 

 

- 용량이 적다.

 

 

 

 

 

3. JSON 형식

 

 

- javascript의 객체의 형식과 같이 {}(중괄호)로 묶어줍니다.

 

 

- "name" : "value"의 쌍으로 이루어져 있습니다. 

 

 

- "name" : "value" 쌍 사이는 ,(쉼표)로 구분하여 줍니다.

 

 

- key는 ""(쌍따옴표)로 묶어주며 문자열의 경우도 ""로 묶어줍니다.

 

 

- 객체안에 문자열, 정수, 배열[], 객체{} 등이 포함 될 수 있습니다

 

 

 

 

4. 예시형식

 

 

- 우리가 회원가입을 하거나 회원정보를 수정하거나 할 시 메일로 축하 메일이나 확인메일이 가곤 하는 것을

   경험한 적이 있으실 것 입니다.

 

 

- 그래서 이번에는 서버에서 PHPMailer를 이용하여 구글에 메일을 발송하는 것을 정리해보겠습니다.

 

 

- 저 같은 경우 aws ec2 임대를 해서 서버를 구축해 놓은 상태에서 진행 하였습니다.

 

 

 

 

1. 라이브러리 사용을 위한 설정.

 

- aws 서버에 접속해서 composer.json에 "require::"phpmailer/phpmailer":"~6.0";을 추가합니다.

 

 

- 그 후 composer install 을 해줍니다.

(저 같은 경우 이미 install 되어 noting to install 이 나오네요~)

 

 

-php 설정파일 디렉토리로 가서 php.ini파일을 열고 openssl쪽이 주석처리 되어있으면 주석을 풀어줍니다.

 

 

 

2.SMTP서버 셋팅

 

-간단합니다. 밑에 내용그대로 허용해주시면 됩니다.

 

 

3. Gmail IMAP 허용

 

 

 

 

4. 계정에 대한 엑세스 허용

 

- 계속 SMTP: Couldn't Authenticated라는 오류가 계속 나와서 aws 내의 보안 규칙도 수정해보고 했으나

  오류가 지속되어서 네이버로 설정해서 보냈더니 네이버는 보내지는 겁니다....!

 

 

-알고보니 여기서 엑세스 허용을 해야 지메일로 보내지는게 가능했습니다.

 

 

- 밑의 링크로 접속해 본인계정을 허용해주도록 합시다(사용할 계정)

 

 

-accounts.google.com/DisplayUnlockCaptcha

 

 

 

 

5. phpmailer 사용 및 소스코드 예시

 

- $mail->Username에는 지메일과 $mail->Password에는 지메일의 비밀번호를 입력하시면 됩니다.

 

 

-이렇게 했는데 안되시면 댓글 달아주세요......! 

'Web & App > Php' 카테고리의 다른 글

PDO (PHP Data Object) 란?  (0) 2020.10.13
php - mysql 연동시 한글 깨짐 현상  (0) 2020.08.17

1. 페이지네이션(페이징) 이란 ?

- 서버와 클라이언트의 상황에서 보통 모든 데이터를 한 번에 가져오지 않습니다.

 

- 보통 필요한 갯수를 지정하고 상황에 맞춰 정렬기준이 조건에 추가됩니다( 정렬기준 + 갯수)

 

- 이러한 조건을 맞춰서 데이터를 가져오는 것을 Pagenation(페이지네이션), 페이징 이라고 합니다.

 

- 페이지네이션을 처리하는 방법으로는 대표적으로 1. 오프셋 기반 페이지네이션, 2.커서 기반 페이지네이션

  으로 처리 가능합니다.

 

- 비교적 구현이 매우 간단한 오프셋 기반 페이지네이션 부터 살펴보겠습니다.

 

 

 

2. Offset-based Pagination (오프셋 기반)

 

- 제가 사용하는 MySQL로 말씀드리자면 LIMIT을 사용하여 개수를 지정하면 됩니다.

SELECT UserId FROM membership ORDER BY CreateAt desc LIMIT 20,40

 

- 좀 더 일반적인 변수를 사용한 쿼리문은 이렇게 되겠네요

( pagenum -> 페이지(1.2.....) )

( takenum -> 한번에 불러올 데이터(row) 수)

'SELECT UserId FROM membership
ORDER BY CreateAt DESC
LIMIT' + ( $takenum*($pagenum-1))+','+$takenum;

- 이렇듯 매우 직관적이고 이해하기가 쉽습니다. 사용하기도 편하구요.

 

- 보통 밑에 이동할 수 있는 페이지가 있고 페이지를 뛰어 넘어갈 수 있다면 offset 기반입니다.

 

- 하지만 제가 생각하는 가장 와닿는 문제는 예를 들겠습니다.

 

- 사용자가 매우 많은 사이트에서 글을 쓰는 사람이 매우 많다고 하겠습니다.

 

- 초당 평균 20개의 새로운 데이터가 들어온다고 가정하고, 한 페이지당 20개의 데이터를

 

- 보여준다면, 이를 오프셋 기반으로 구현을 한다면 1페이지의 20개의 글을 본 사람이

 

- 2페이지의 글을 보려고 눌렀을때, 방금 본 20개의 데이터를 그대로 다시 보게 됩니다.

 

- 즉, 중복데이터를 출력하게 됩니다. 그리고 이런 최악은 아니더라도 생각보다 이런 상황은

 

- 빈번하게 나타나고, 아마  경험하신 분들도 많이 있으실거라 생각합니다.

 

- 또 다른 문제는, 정렬기준 조건에 따라서 row가 몇번 째 데이터인지 바뀌게 되는데,

 

- 당연히 DB는 모든 경우에 따른 rownum을 가지고 있지 않기때문에 

 

- row의 수가 많아질수록 성능에 문제가 생기게 됩니다.

 

-이러한 단점을 보완해줄 수 있는 것이 커서 기반 페이지네이션 입니다.

 

 

 

3. Cursor-based Pagination (커서 기반)

 

- 음.... cursor를 포인터라고 생각하면 이해가 빠를 것 같습니다.

 

- cursor를 만들어 놓고 "이 cursor가 가리키는 것 다음 부터 n개의 데이터를 주세요" 하는 방식입니다.

 

- 오프셋 방식을 굳이 예로 들자면 "n개의 데이터를 page-1만큼 스킵하고 그 다음부터 n개의 데이터를 주세요"

  가 될 것 같네요.

 

- 만약 cursor가 int로 된 UserId라면 UserId 자체를 커서로 사용하여도 상관이 없습니다. (UserId - PK)

 

- 하지만 cursor를 회원가입 시기(CreateAt) 라고 지정한다면 어떻게 될까요?????

(데이터가 만들어진 순서대로 출력하고 싶을 때)

 

- 상황 설명을 위해 LIMIT를 사용해서 현재 가정한 테이블의 상태를 확인해보겠습니다.

  (CreateAt은 설명의 편의성을 위해서 간단한 숫자로 대체하여 표현하겠습니다.)

 

SELECT UserId,CreateAt FROM membership 
ORDER BY CreateAt ASC LIMIT 4

 

UserId CreateAt
123 1
124 2
120 3
114 4

 

- 전혀 문제가 없어 보입니다. 하지만 만약에 UserId가 "114"와 동시에 가입한 115,116,117이 있을경우

 

- cursor를 CreateAt으로 설정할 경우 cursor>4 인 리스트를 다음페이지에 불러올 텐데 그럴경우

 

- 115,116,117의 데이터는 누락이 발생합니다.

 

- 여기서 알 수 있는 것은

 

- "커서 기반 페이지네이션을 위해서는 정렬 기준에 포함되는 필드 중 하나이상은 반드시 고유값을 가져야 한다는 것 "

 

- 설명을 위해 테이블의 상황을 살짝 수정하겠습니다. 아래와 같습니다.
  (말이 좀 안되지만 age는 중복값이 없는 고유값이라고 가정을 좀 하겠습니다.)

UserId CreateAt Age
123 1 17
124 2 18
120 3 19
114 4 20

- 이 다음 페이지의 데이터를 얻기 위해서는 다음과 같은 쿼리를 날리면 됩니다.

 

SELECT UserId,CreateAt,Age FROM membership
WHERE (CreateAt >4) or (CreateAt=4 and Age>20)
ORDER BY CreateAt ASC, Age ASC LIMIT 4

- 이렇게 날리면 CreateAt이 4 인 115,116,117도 누락되지 않습니다.

 

- 문제가 모두 해결된 것 처럼 보이지만 여기서도 제가 생각하는 문제점 중 하나는

 

- 이렇게 조건절에 필요사항이 달림에 따라서 클라이언트 측에서도 이를 이해하고

 

- ORDER BY에 달려있는 필드 들을 이해하고 이에 해당하는 값들을 요청시 마다 보내야 하는데

 

- 당연히 클라이언트 측은 그걸 좋아하지 않고 원치 않습니다

 

- 그러므로 WHERE절에 걸리는 조건들을 이용해서 고유한 값인 CURSOR(커서)를 만들면 됩니다.

 

- 간단한 예시로 CreateAt이 최대 6자라고 하고 AGE가 최대 3자 라고 가정하면,

  

- 두 가지를 합쳐서 "4" + "17" => "000004017" 이런 식으로 가공하여 CURSOR 값으로 사용을 하는 것입니다.

 

- 커서를 기준으로 출력 후 , 그 다음 리스트는 이 커서 기준으로 다음부터 데이터를 가져오면

 

- 위의 문제들이 해결된다는 것을 알 수 있습니다.

 

 

 

 

 

4. Offset vs Cursor

 

- 제 생각에는 왠만하면 커서를 이용하는 것이 좋은 것 같습니다만

 

- 데이터의 입력이 매우 드물고, 또는 중복되는 데이터가 나와도 크게 상관이 없는경우

 

- 데이터의 수 자체가 그리 많지 않아서 성능에 딱히 연연하지 않아도 되는 경우

 

- 등에서는 오프셋을 사용해도 크게 문제되지는 않을 것 같습니다.

 

- 하지만 유저가 접속해서 사용하는 경우 커서 기반을 사용하는 것이 좋습니다.

'Web & App > Mysql' 카테고리의 다른 글

Query문의 실행 순서  (2) 2020.10.27
mysql 외부 접속 허용  (0) 2020.08.17

+ Recent posts