내가 겪은 문제
Communication Link Failure 라는 에러와 time_out이 발생하면서 JDBC 와 Mysql 연결이 안됐음
환경
DBMS : Mysql 8.0.27
Server : Ubuntu 20.04
Client : Windows 10
IDE : Intellij ( Java 17 version )
자바 다운받는 곳 (java 17 version)
https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
먼저 자신의 버전에 호환되는 JDBC 를 다운로드 받는다.
나는 mysql이 8.0.27이라 mysql-connector-java 8.0.27 을 다운받았다.
https://downloads.mysql.com/archives/c-j/
실질적으로 JDBC에서 필요한 것은 jar 파일이고 나의 OS가 windows여서 ZIP 파일을 다운받았다.(우분투면 tar 받으세요)
** 서버의 mysql 버전 잘 확인하고 받으세요 ubuntu 기준 mysql --version 명령어 치면 나옵니다. **
압축을 풀면
해당 jar 파일이 나오는데 이 mysql-connector-java-8.0.27를 옮겨주면된다.
java 파일 안에 위치시켜줘야하는데 JDK 17을 기본설치를 했으면
C:\Program Files\Java\jdk-17.0.1\lib 안에 넣어주면 된다. - 꼭 해줘야되는 부분인지는 모르겠다.
옮겼으면 intellij에서 프로젝트를 하나 판다. new Project 생성을 클릭하고
나는 이미 jdk를 추가해놔서 찾아져있지만 처음 intellij를 받았으면 Add JDK 를 클릭 후
C:\Program Files\Java\jdk-17.0.1 를 클릭하면 된다.
다음 버튼을 클릭하다가 원하는 Title을 지정 후 프로젝트 생성.
JDBC 프로젝트와 연결
File - Project Structure
Libaries에서 + 버튼을 누르고 아까 옮겨놓은 mysql-connector-java-8.0.27.jar 파일을 클릭 후 확인버튼으로 적용 시켜주면 된다.
프로젝트에 External Libaries에 jdbc가 추가되어있으면 성공적으로 된 거다.
연결이 되는지 테스트하는 코드이다.
URL에 당신 서버의 주소를 적는다.
로컬이라면 127.0.0.1 그대로 하고 서버가 있다면 서버의 주소와 mysql과 연결할 포트번호가 기본포트인 3306 포트 말고 다른 포트면 포트번호를 적어준다
(3306포트 그대로 하거나 설정을 바꾼적이 없으면 jdbc:mysql://127.0.0.1/db명 만 작성해도 된다.)
import java.sql.*;
public class ConnectionTest {
private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String URL = "jdbc:mysql://127.0.0.1:열려있는 포트/DB명";
private static final String USER = "mysql 유저 ID";
private static final String PW = "mysql 유저 PW";
public static Statement stmt;
public static void main(String[] args) {
Connection conn = null;
try {
//드라이버 연결
Class.forName(DRIVER);
//접속 URL, mysql 유저 아이디, 비밀번호로 접속
conn = DriverManager.getConnection(URL, USER, PW);
//접속성공 메세지
System.out.println("Database connection established");
} catch (Exception e) {
//예외 발생시 메세지
System.err.println("Cannot connect to database server");
System.err.println(e.getMessage());
e.printStackTrace();
}
finally {
if (conn != null) {
try {
conn.close();
System.out.println("Database Connection Terminated");
} catch (Exception e) {}
}
}
}
}
연결이 성공하면 다음 메세지들이 나온다.
연결이 안되고 에러메세지가 뜰 시 확인해야할 부분들 **중요**
(나의 경우 Communication Link Failure와 Timeout 에러가 발생)
1. URL 잘못썼는지 다시한번 확인
URL 에서 ip 제대로 작성했는지 확인
jdbc:mysql://127.0.0.1/db명 ----> 포트가 3306이 아니면 꼭 ip 뒤에 :포트번호 작성해줘야함
2. mysql 설정에 bind-address 확인
mysql 패키지 다운로드 했을 시
vi /etc/mysql/mysql.conf.d/mysqld.cnf
mysql 설정 파일 안에
1. bind-address와 mysqlx-bind-address 부분을 둘다 주석처리해준 후 저장
2. mysql 재시작
service mysql restart
3. mysql 유저 권한 확인
mysql 접속 후
use mysql;
유저 권한 확인
SELECT host,user FROM mysql.user;
host 부분에 %는 누구나 접속하길 허용한다는 뜻, localhost는 localhost만 허용한다는 뜻
만약!! 같은 user 아이디(root를 제외한)에 %와 localhost가 둘 다 host에 존재한다면 %는 무시될 수 있음
mysql 공식문서에서 확인했음. 나의 경우엔 sewang 유저로 접속하는데
root 유저의 host에 보이는 것처럼 %, localhost 둘 다 있어서
내가 접속하려는 유저(sewang)의 localhost 권한을 없애고 %권한만 남겨놓으니 문제가 해결됐음
4. 포트 확인 및 방화벽 확인
1) 포트확인
포트 열려있는지 확인하는 명령어
netstat -nap | grep LISTEN
이렇게되면 수신중인 포트를 확인할 수 있다.
mysql 3306포트가 열려있어야한다.
열려있어도 안될 때가 있다 (** 내가 문제를 해결한 부분 **)
우분투 내부 방화벽에 포트를 열어줘야한다.
vim /etc/iptables/rules.v4
해당 코드 추가 후 저장 (3306을 원하는 포트로 바꿔도됨)
-A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
해당 코드를 꼭 -A RH-Firewall-l-INPUT -j REJECT --reject-with icmp-host-prohibited 코드 위에 작성해야한다.
밑에 작성하면 적용이안됩니다.
iptable 재시작
$ sudo service iptables restart
2) 임대서버 방화벽
임대서버를 쓰고있다면 inbound, outbound에 포트포워딩 꼭 해줄 것 ( 각자의 임대서버에 맞는 포트포워딩이 있음 구글링하면 나옴)
임대서버가 아니라면 ufw 등 방화벽에 맞는 방화벽 포트 해제 확인
여기까지 했는데 안됐으면 일단 서버로 ping 전송이 되는지 확인한다.
1) cmd 창 오픈 - windows키 + R
2) 해당 파일이 저장되어있는 경로로 이동
3) ping 주소값 포트번호
ex) ping 49.xxx.xxx.xxx 3306
정상 : 패킷 보냄 4 받음 4 손실 0
비정상 : 패킷 보냄 4 받음 0 손실 4
패킷전송이 안된다면 포트가 안열려있을 가능성이 크다.
패킷전송이 된다면 mysql 자체의 문제일 듯 하지만 겪어보지 않아서 잘 모르겠다.
같은 문제를 다시는 겪지 않길 바라며 첫 포스트 작성 완료!!
'Java' 카테고리의 다른 글
Apache JMeter - nginx-rtmp 미디어서버 성능테스트 HLS livestreaming (0) | 2022.07.06 |
---|---|
Apache JMeter - 설치 및 사용법 (웹서버 성능테스트) (0) | 2022.07.05 |
[JDBC] 자바에서 sql 문 처리하기 (1) | 2021.12.22 |
댓글