ไม่สามารถเชื่อมต่อกับ mysql ผ่านตัวเชื่อมต่อ JDBC ผ่าน Tomcat หรือภายนอก


17

ฉันได้ติดตั้งการติดตั้งคลัง mysql 5.5 และในขณะที่ฉันสามารถเชื่อมต่อกับบริการ mysql ผ่านคำสั่ง mysql ได้และดูเหมือนว่าบริการจะทำงานอยู่ฉันไม่สามารถเชื่อมต่อกับสปริง + tomcat หรือจากตัวเชื่อมต่อ jdbc ภายนอกได้

ฉันใช้ URL ต่อไปนี้:

jdbc:mysql://myserver.com:myport/mydb

ด้วยชื่อผู้ใช้ / รหัสผ่านที่เหมาะสม แต่ฉันได้รับข้อความต่อไปนี้:

server.com: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. the driver has not received any packets from the server.

และ Tomcat พ่น:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)

ซึ่งดูเหมือนว่าจะเป็นปัญหาเดียวกันกับถ้าฉันพยายามที่จะเชื่อมต่อภายนอก


ฉันประสบปัญหานี้เมื่อพยายามเชื่อมต่อผ่านจาวากับฐานข้อมูล mysql ของฉันซึ่งทำงานบนเซิร์ฟเวอร์อื่นใน LAN ของฉัน เมื่อรันโปรแกรมจาวาเดียวกันบนเซิร์ฟเวอร์ที่รัน mysql มันกำลังเชื่อมต่อโดยไม่มีปัญหา จากเครื่องภายนอกฉันสามารถเชื่อมต่อกับฐานข้อมูล mysql โดยใช้ SQLYog เช่น (แม้ว่าฉันจะต้องเปลี่ยนไฟล์ my.cnf เป็นผูกเป็น 0.0.0.0 แทนที่จะเป็น 127.0.0.1) คำตอบของ Boden และความคิดเห็นเกี่ยวกับการเปลี่ยนขั้วต่อ JDBC ทำให้ฉันไปในทิศทางที่ถูกต้อง ฉันเปลี่ยนขั้วต่อ JDBC เป็นเวอร์ชันล่าสุดและทันใดนั้นก็ใช้งานได้!
user2380870

คำตอบ:


18

สิ่งนี้สามารถเกิดขึ้นได้จากหลายสาเหตุ ฉันเพิ่งเห็นมันเองเมื่อไม่กี่สัปดาห์ที่ผ่านมา แต่ฉันจำไม่ได้ว่าการแก้ไขนั้นมีอะไรสำหรับฉัน

1) ตรวจสอบว่าที่อยู่ mysql ถูกผูกไว้อาจเป็น 127.0.0.1 (เท่านั้น) ซึ่งฉันเชื่อว่าเป็นค่าเริ่มต้น (อย่างน้อยบนเซิร์ฟเวอร์ Ubuntu มาตรฐาน) คุณจะต้องแสดงความคิดเห็นพารามิเตอร์ที่อยู่ผูกใน my.cnf เพื่อผูกกับที่อยู่ที่มีอยู่ทั้งหมด (คุณไม่สามารถเลือกได้หลายรายการเป็นหนึ่งหรือทั้งหมด)

2) ถ้ามันถูกผูกไว้กับ 127.0.0.1 และคุณไม่สามารถเชื่อมต่อโดยใช้ "localhost" ตรวจสอบให้แน่ใจว่าไม่ได้แก้ไขไปยังที่อยู่ IPv6 localhost แทน IPv4 (หรือเพียงแค่ใช้ที่อยู่ IP)

3) ตรวจสอบพอร์ตที่ mysql กำลังฟังอยู่

4) ตรวจสอบให้แน่ใจว่าคุณกำลังใช้ตัวเชื่อมต่อ JDBC ที่เหมาะสมสำหรับ JDK ของคุณ

5) ตรวจสอบให้แน่ใจว่าคุณไม่ได้ทำอะไรที่โง่ ๆ เช่นเริ่ม mysql กับ --skip-networking

ฉันคิดว่าคำแนะนำแรกของฉันมีสัญญามากที่สุด ... อันที่จริงฉันคิดว่านั่นคือสิ่งที่ฉันเห็นเมื่อเร็ว ๆ นี้ ... ฉันพยายามเชื่อมต่อกับ mysql จากระยะไกล (เช่นเดียวกับ Ubuntu 8.04)


เพียงเพิ่ม 2 เปอร์เซ็นต์ของฉันสิ่งที่สี่ก็ใช้ได้สำหรับฉัน ขอบคุณ!
Janis Peisenieks

1
เกี่ยวกับ "คุณจะต้องแสดงความคิดเห็นพารามิเตอร์ที่อยู่ผูกใน my.cnf เพื่อผูกกับที่อยู่ที่มีอยู่ทั้งหมด" เริ่มต้นคือตอนนี้ฟังเฉพาะใน localhost ดังนั้นคุณอาจต้องใช้บรรทัด "bind-address = 0.0 0.0 "ภายใน [mysqld]
Palo

13

ฉันมีปัญหาเดียวกันในสองโปรแกรมของฉัน ข้อผิดพลาดของฉันคือ:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.

ฉันใช้เวลาหลายวันเพื่อแก้ปัญหานี้ ฉันได้ทดสอบวิธีการมากมายที่ได้กล่าวถึงในเว็บไซต์ต่าง ๆ แต่ไม่ใช่วิธีการทำงาน ในที่สุดฉันก็เปลี่ยนรหัสและพบว่าปัญหาคืออะไร ฉันจะพยายามที่จะบอกคุณเกี่ยวกับวิธีการที่แตกต่างกันและรวมพวกเขาขึ้นที่นี่

ในขณะที่ฉันกำลังค้นหาอินเทอร์เน็ตเพื่อค้นหาวิธีแก้ไขปัญหาสำหรับข้อผิดพลาดนี้ฉันพบว่ามีวิธีแก้ไขปัญหามากมายที่ใช้งานได้อย่างน้อยหนึ่งคน แต่คนอื่นบอกว่าไม่เหมาะกับพวกเขา! ทำไมมีหลายวิธีในการแก้ไขข้อผิดพลาดนี้? ดูเหมือนว่าข้อผิดพลาดนี้สามารถเกิดขึ้นได้โดยทั่วไปเมื่อมีปัญหาในการเชื่อมต่อไปยังเซิร์ฟเวอร์ บางทีปัญหาอาจเกิดจากสตริงข้อความค้นหาที่ไม่ถูกต้องหรือมีการเชื่อมต่อกับฐานข้อมูลมากเกินไป

ดังนั้นฉันขอแนะนำให้คุณลองใช้โซลูชันทั้งหมดทีละตัวและอย่ายอมแพ้!

นี่คือคำตอบที่ฉันพบบนอินเทอร์เน็ตและสำหรับแต่ละคนมีอย่างน้อยในคนที่ปัญหาของเขาได้รับการแก้ไขด้วยวิธีแก้ปัญหานั้น

จุด: สำหรับโซลูชั่นที่คุณต้องเปลี่ยนการตั้งค่า MySQL คุณสามารถดูได้จาก:

  • Linux: /etc/my.cnf

  • Windows: D: \ Program Files \ mysql \ bin \ my.ini

นี่คือโซลูชั่น:

  • การเปลี่ยนแอตทริบิวต์ "bind-address"

แอตทริบิวต์ Uncomment "bind-address" หรือเปลี่ยนเป็นหนึ่งใน Ips ต่อไปนี้:

ผูกอยู่ = "127.0.0.1"

หรือ

ผูกอยู่ = "0.0.0.0"

  • แสดงความคิดเห็นออก "ข้ามเครือข่าย"

หากมีบรรทัด "การข้ามเครือข่าย" ในไฟล์ MySQL config ของคุณให้แสดงความคิดเห็นโดยเพิ่มเครื่องหมาย "#" ที่จุดเริ่มต้นของบรรทัดนั้น

  • เปลี่ยน "wait_timeout" และ "interactive_timeout"

เพิ่มบรรทัดเหล่านี้ไปยังไฟล์ MySQL config:

wait_timeout = จำนวน

interactive_timeout = จำนวน

connect_timeout = หมายเลข

  • ตรวจสอบการตั้งค่าพร็อกซีของระบบปฏิบัติการ

ตรวจสอบให้แน่ใจว่าไฟร์วอลหรือซอฟต์แวร์ป้องกันไวรัสไม่ปิดกั้นบริการ MySQL

  • เปลี่ยนสตริงการเชื่อมต่อ

ตรวจสอบสตริงการสืบค้นของคุณ สตริงการเชื่อมต่อของคุณควรเป็นดังนี้:

dbName = "my_database";
dbUserName = "root";
dbPassword = "";
String connectionString = "jdbc:mysql://localhost/" + dbName + "?user=" + dbUserName + "&password=" + dbPassword + "&useUnicode=true&characterEncoding=UTF-8";

ตรวจสอบให้แน่ใจว่าคุณไม่มีช่องว่างในสตริง สตริงการเชื่อมต่อทั้งหมดควรดำเนินการต่อโดยไม่มีอักขระเว้นวรรค

ลองแทนที่ "localhost" ด้วยพอร์ตของคุณเช่น 127.0.0.1 ลองเพิ่มหมายเลขพอร์ตในสตริงการเชื่อมต่อของคุณเช่น:

String connectionString = "jdbc:mysql://localhost:3306/my_database?user=root&password=Pass&useUnicode=true&characterEncoding=UTF-8";

โดยปกติแล้วพอร์ตเริ่มต้นสำหรับ MySQL คือ 3306

อย่าลืมเปลี่ยนชื่อผู้ใช้และรหัสผ่านเป็นชื่อผู้ใช้และรหัสผ่านของเซิร์ฟเวอร์ MySQL ของคุณ

  • อัพเดตไฟล์ไลบรารีไดรเวอร์ JDK ของคุณ
  • ทดสอบ JDK และ JREs ที่แตกต่างกัน (เช่น JDK 6 และ 7)
  • อย่าเปลี่ยน max_allowed_packet

" max_allowed_packet " เป็นตัวแปรในไฟล์ MySQL config ที่ระบุขนาดแพ็คเก็ตสูงสุดไม่ใช่จำนวนแพ็คเก็ตสูงสุด ดังนั้นจะไม่ช่วยแก้ไขข้อผิดพลาดนี้

  • เปลี่ยนความปลอดภัยโพงแคท

เปลี่ยน TOMCAT6_SECURITY = ใช่เป็น TOMCAT6_SECURITY = ไม่

  • ใช้คุณสมบัติ validationQuery

ใช้ validationQuery = "select now ()" เพื่อให้แน่ใจว่าแบบสอบถามแต่ละคำตอบ

  • AutoReconnect

เพิ่มรหัสนี้ในสตริงการเชื่อมต่อของคุณ:

&autoReconnect=true&failOverReadOnly=false&maxReconnects=10

แม้ว่าวิธีการเหล่านี้จะไม่เหมาะกับฉัน แต่ฉันขอแนะนำให้คุณลองใช้ เพราะมีบางคนแก้ปัญหาด้วยการทำตามขั้นตอนเหล่านี้

แต่สิ่งที่แก้ปัญหาของฉันได้อย่างไร ปัญหาของฉันคือฉันมี SELECT จำนวนมากบนฐานข้อมูล ทุกครั้งที่ฉันสร้างการเชื่อมต่อแล้วปิด แม้ว่าฉันจะปิดการเชื่อมต่อทุกครั้ง แต่ระบบต้องเผชิญกับการเชื่อมต่อจำนวนมากและทำให้ฉันมีข้อผิดพลาด สิ่งที่ฉันทำคือฉันกำหนดตัวแปรการเชื่อมต่อของฉันเป็นตัวแปรสาธารณะ (หรือส่วนตัว) สำหรับชั้นเรียนทั้งหมดและเริ่มต้นได้ในตัวสร้าง จากนั้นทุกครั้งที่ฉันใช้การเชื่อมต่อนั้น มันแก้ปัญหาของฉันและยังเพิ่มความเร็วของฉันอย่างมาก

ข้อสรุป

ไม่มีวิธีที่ง่ายและไม่เหมือนใครในการแก้ปัญหานี้ ฉันแนะนำให้คุณคิดถึงสถานการณ์ของคุณและเลือกวิธีแก้ไขปัญหาข้างต้น หากคุณใช้ข้อผิดพลาดนี้ที่จุดเริ่มต้นของโปรแกรมและคุณไม่สามารถเชื่อมต่อกับฐานข้อมูลได้ทั้งหมดคุณอาจมีปัญหาในสตริงการเชื่อมต่อของคุณ แต่ถ้าคุณใช้ข้อผิดพลาดนี้หลังจากประสบความสำเร็จหลายครั้งในการโต้ตอบกับฐานข้อมูลปัญหาอาจเกิดจากจำนวนการเชื่อมต่อและคุณอาจคิดถึงการเปลี่ยน "wait_timeout" และการตั้งค่า MySQL อื่น ๆ หรือเขียนรหัสของคุณใหม่


ฉันมีปัญหานี้ด้วย! แต่ตอนแรกฉันเปลี่ยน mysql เพื่อฟังพอร์ต 8888 แทนที่จะเป็น 3306 ดังนั้นคำตอบของ @ sohail ช่วยฉันเพิ่งเพิ่มพอร์ต 8888 ไปยัง uri ของฉันและมันทำงานได้! ขอบคุณมัด

วิธีนี้แก้ไขปัญหาให้ฉันได้! ด้วยการตั้งค่า Vagrant Homestead ของเราด้วยเหตุผลบางอย่างก็ผูกพันกับที่อยู่ที่ให้ไว้กับ VM (10.0.2.15 ในกรณีของฉัน) แทน localhost
แลนเดอร์

1

หากคุณใช้การติดตั้ง Linux คุณอาจมี lokkit ที่บล็อกการสื่อสารขาเข้ายกเว้นผ่านทาง SSH

ล็อกอินด้วยรูทแล้วรันคำสั่ง lokkit จากพรอมต์ปิดใช้งานไฟร์วอลล์และ SElinux แล้วดูว่าคุณมีปัญหาเดียวกันหรือไม่

ตรวจสอบการอนุญาตของคุณอย่างถูกต้องเพื่อให้ทุกอย่างสามารถเขียนไปยังตำแหน่งที่ถูกต้อง


ฉันใช้ Ubuntu 8.04 ฉันอาจจะต้องพูดถึงเรื่องนั้น คุณมีคำแนะนำเฉพาะสำหรับ distro นั้นหรือไม่? เดี๋ยวก่อนฉันจะ google แต่ฉันคิดว่าฉันจะถามก่อน
Stefan Kendall

sudo ufw disable จะปิดใช้งาน Ubuntu Firewall
Stephen Thompson

ฉันติดตั้ง ufw และพยายามเปิดใช้งานพอร์ต แต่ไม่มีลูกเต๋า
Stefan Kendall

ถอนการติดตั้ง ufw และ iptables แล้ว ฉันคิดว่า ufw เป็นเครื่องมือการจัดการที่ต้องติดตั้งแยกต่างหาก แน่นอนว่า "iptables" ไม่มีคำสั่งดังกล่าวและดูเหมือนว่าจะไม่มีบริการ iptables
Stefan Kendall

ตกลงสิ่งสุดท้ายที่ฉันพบบ่อยคือคุณไม่ได้เปิดใช้งาน mysql เพื่อฟังบนอินเตอร์เฟส eth0 และบ่อยครั้งที่มันจะอยู่บนอินเตอร์เฟส localhost เท่านั้น ลองทำสิ่งต่อไปนี้ เปลี่ยน jdbc: mysql: //myserver.com: myport / mydb เป็น jdbc: mysql: // localhost: myport / mydb หากใช้งานได้คุณต้องทำdev.mysql.com/doc/refman/5.1/en/
Stephen Thompson

1

นอกจากนี้ยังมีข้อผิดพลาดขนาดใหญ่ในเวอร์ชั่น 5.1.9 ของไดรเวอร์ mysql-jdbc นี้:

http://bugs.mysql.com/bug.php?id=47494


1

นอกจากนี้ยังอาจเกิดจากการที่ไม่ถูกต้องตั้งค่าพร็อกซี่ ฉันมีปัญหานี้พยายามเชื่อมต่อผ่าน jdbc กับอินสแตนซ์ MySQL ที่ทำงานในอุปกรณ์เสมือนของ Parallels บน Mac ของฉัน การเชื่อมต่อ jdbc ใช้การตั้งค่าเครือข่ายระดับระบบและเนื่องจากฉันอยู่หลังพร็อกซี SOCKS ฉันต้องตั้งค่าโฮสต์ MySql เป็นโฮสต์ที่ไม่ใช่พร็อกซี่ (เช่นบน Mac คุณสามารถกำหนดค่าในการตั้งค่า -> เครือข่าย -> ขั้นสูง - > พรอกซีและสุดท้ายเพิ่มชื่อโฮสต์หรือที่อยู่ IP ใน "การตั้งค่าพร็อกซีบายพาสสำหรับโฮสต์และโดเมนเหล่านี้")


1

MySQL Connector / J รองรับเฉพาะ TCP / IP Java ไม่รองรับการเชื่อมต่อซ็อกเก็ตโดเมน Unix

หาก MYSQL เริ่มต้นด้วยการตั้งค่าสถานะการข้ามเครือข่ายหรือหาก MySQL ทำงานอยู่หลังไฟร์วอลล์ตัวเลือก TCP / IP จะถูกปิดใช้งาน เพื่อให้ Java ไม่สามารถสื่อสารกับ MySQL


0

ฉันมีปัญหาที่คล้ายกันมากสำหรับเกือบหนึ่งวันและมันทำให้ฉันบ้า! แต่ฉันจัดการเพื่อหาวิธีแก้ปัญหาและมันง่ายมากคุณเพียงแค่ต้อง /etc/init.d/tomcat6 เพื่อเปลี่ยน TOMCAT6_SECURITY = ใช่เป็น TOMCAT6_SECURITY = ไม่ มันไม่ใช่ทางออกของฉันฉันพบที่นี่อย่างที่คุณเห็นฉันกำลังใช้ Ubuntu หวังว่าจะได้ผล


0

ผมมีปัญหาเดียวกัน. เปลี่ยนคุณสมบัติ "bind-address" ในไฟล์ /etc/mysql/my.cnf เป็น 0.0.0.0 และใช้งานได้ บรรทัดที่สอดคล้องกันใน my.cnf มีลักษณะเช่นนี้:

bind-address = 0.0.0.0

ก่อนที่มันจะถูกตั้งค่าเป็นที่อยู่ IP ภายนอกของเซิร์ฟเวอร์ดังนั้นมันจึงดูเหมือน:

bind-address = 196.152.4.145

ฉันคิดว่าเมื่อมันถูกตั้งค่าเป็นที่อยู่ IP ภายนอกและไม่ใช่ลูป localhost เซิร์ฟเวอร์ mysql จะเชื่อมต่อกับการ์ดเครือข่ายและไม่ฟังการเชื่อมต่อจากลูปในเครื่อง


0

ลองที่อยู่ในพื้นที่ของคุณเพื่อผูกที่อยู่ในไฟล์ my.cnf

การเชื่อมต่อ = null;

    try {
        Class.forName("com.mysql.jdbc.Driver");
        con = DriverManager.getConnection("jdbc:mysql://x62.xx8.x4x.x5:3306/mydb", "root", "root");
        try {
            System.out.println(con.getMetaData());
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } catch (ClassNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.