ไม่สามารถเชื่อมต่อกับ 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.