mssql server
를 설치하여 db를 연동하였다.
마무리 단계이다.
docker를 활용해서 설치하였다. aws ec2에 설치하려고 했는데 메모리 용량 이슈 때문에 로컬에 설치했다(프리 티어 사용 중)
docker run \
-e 'ACCEPT_EULA=Y' \
-e 'MSSQL_SA_PASSWORD=YourStrongPassword123!' \
-p 1433:1433 \
--name mssql_server -d mcr.microsoft.com/mssql/server:2022-latest
위 명령어를 실행하였더니 도커로 아주 손쉽게 설치할 수 있었다. 예전에 mssql을 로컬에 직접 설치한 적이 있는데 별로 까다롭지는 않았지만, docker로 간단히 설치하니 너무 쉬웠다.
-- 추가 내용
parking server
또한 docker로 띄우기 때문에 connection string을 만들 때, localhost
를 인식할 수 없기 때문에 docker network를 설정해주어야 한다.
또한, 볼륨 마운트를 해야지 컨테이너를 삭제했을 때, db가 남아있다고 한다.
// docker network 생성
docker network create mssql_network
// docker data 생성
docker volume create mssql_data
// 추가로 볼륨 마운트 + 네트워크 설정 추가
-v mssql_data:/var/opt/mssql
--network mssql_network
// run-docker.bat 수정
docker run ^
--rm ^
--name parking_server ^
--network my_mqtt_net ^
--network mssql_network ^ // db network 추가
-v "%cd%:/app" ^
--workdir "/app" ^
parking_server ^
cargo run
// .env 파일 수정
Connection String 설정 시
localhost -> mssql_db 수정
입출차한 차량에 대한 정보를 저장하면 된다.
정도로 컬럼을 설정하기로 하였고, parking_id
는 자동 증분으로 설정하고 pk로 지정하였다.
번호판에 한글이 있어서 license_plate
를 nvarchar(20)
으로 설정 후
Insert into Parking.dbo.ParkingRecords (license_plate, entry_time, is_paid, is_discounted)
values ('123가3456', 1231231, 0, 0)
위 처럼 넣어주니깐 한글이 깨지는 이슈가 있었다. 찾아보니깐 유니코드 형식으로 넣어주려면 N
을 붙인 뒤 넣어줘야 한다고 한다.
values (N'123가3456', 1231231, 0, 0)
rust에서 mssql
을 손쉽게 사용할 수 있도록 지원해주는 라이브러리인 tiberius
를 사용하였다.
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 1. .env 파일 로드
dotenv().ok();
println!("연결 시도 중...");
let config = Config::from_ado_string(&CONN_STR)?;
let tcp = TcpStream::connect(config.get_addr()).await?;
tcp.set_nodelay(true)?;
// Tiberius 클라이언트 생성
let mut client = Client::connect(config, tcp.compat_write()).await?;
println!("MSSQL 연결 성공!");
// 쿼리 실행
let query = format!(
"SELECT TOP 5 parking_id, license_plate, entry_time FROM Parking.dbo.ParkingRecords ORDER BY entry_time DESC"
);
println!("\n쿼리 실행 중: {}", query);
let stream = client.query(query, &[]).await?;
let row = stream.into_row().await?.unwrap();
println!("{:?}", row);
Ok(())
}
아주 간단하게 bin/db_test.rs
에서 테스트하였다.
https://github.com/prisma/tiberius/blob/main/examples/tokio.rs 여기를 참조하였다.
db
를 다룰 때, 연결을 쿼리마다 한다면 오버헤드가 발생하므로 최초에 db connection pool을 만들어 필요할 때 pool에서 빌려서 사용하는 방식으로 구현한다고 한다. 그래서 찾아보았더니 bb8-tiberius
라는 라이브러리가 있어서 사용하여 손쉽게 구현하였다. 정확히 몇 개의 컨넥을 생성 후 pool에서 가지고 있어야 하는지는 추후 테스트를 통해서 정확히 해야 할 것 같다.
입차 요청이 온 뒤 ocr을 통해 번호판을 파싱하고 응답을 보내기 전 db를 저장하도록 설계하였다. db task를 따로 만들어서 비동기로 처리하도록 했다. 이후 실패에 대한 처리가 필요할 것 같다.
ocr 파싱과 db에 insert가 모두 정상적으로 된 것을 확인할 수 있다.
db pool을 활용해 미리 컨넥션을 만들어서 pool에 저장한 형태로 사용하는 테크닉을 알았고, 무조건 연결을 하는 것은 아니라는 것도 알았다. 컨넥션에 대한 세팅을 한 상태에서 실제 풀에서 땡겨올 때 연결을 하기도 하는 것 같다. db까지 성공적으로 기능 추가했으므로, 최종 로직을 구현 후 포스팅하겠다.