เมื่อไม่นานมานี้ฉันวางแผนที่จะสร้างบริการค้นหาง่าย ๆ สำหรับโครงการ แม้ว่าฐานข้อมูลธุรกิจ MongoDB ให้การสนับสนุนการค้นหาข้อความ แต่เมื่อต้องใช้เอกสารจำนวนมากผ่านคำหลัก แต่เห็นได้ชัดว่าเหมาะสมกว่าเป็นเครื่องมือค้นหา (แม้ว่าเราส่วนใหญ่เคยใช้การวิเคราะห์และการสร้างภาพของ Elk มาก่อน) Elasticsearch สร้างขึ้นบน Lucene และรองรับการสืบค้นที่รวดเร็วมากและไวยากรณ์แบบสอบถามที่หลากหลายและบางครั้งก็ทำหน้าที่เป็น NOSQL ที่มีน้ำหนักเบา อย่างไรก็ตามความสามารถในการสืบค้นที่ซับซ้อนและการดำเนินการรวมนั้นไม่แข็งแกร่งนัก
บทความนี้จะไม่พูดถึงวิธีการสร้างบริการค้นหาอย่างง่าย แต่จะบันทึกข้อผิดพลาดหลายอย่างที่พบในช่วงเวลาทำงานประมาณหนึ่งสัปดาห์ -
ทำไมต้องเลือก ElasticSearch 5.x?
บริการใหม่ไม่มีภาระทางประวัติศาสตร์และในทางทฤษฎีควรใช้ 6.x ล่าสุด อย่างไรก็ตาม Spring-Data-Elasticsearch รองรับ 5.x เท่านั้นและเป็นการยากที่จะห่อหุ้มชั้นของ API โดยตรงแม้ว่าเวลาจะแน่น มันเป็นเพราะสิ่งของรุ่นก่อนหน้าของ Elk สับสนดังนั้นจึงไม่มีทางเลือกนอกจากต้องเปลี่ยนจาก 2.x เป็น 5.x สอบถามความแตกต่างระหว่าง 5.x และ 2.x พูดง่ายๆคือพื้นที่ดิสก์ -50%เวลาดัชนี -50%ประสิทธิภาพการสืบค้น +25%
เนื่องจาก Spring-Data-Elasticsearch ต้องได้รับการอัพเกรดเป็น 3.0.7 สปริงจะต้องอัพเกรดเป็น 2.x ซึ่งนำไปสู่ข้อผิดพลาดที่เกิดขึ้นในภายหลัง
การติดตั้ง Docker ES จะติดตั้งปลั๊กอิน X-Path ตามค่าเริ่มต้น
แม้ว่า Spring-Data รองรับ ES5.X ฟังก์ชั่นของมันยังไม่สมบูรณ์ ดังนั้นหากติดตั้งปลั๊กอิน X-Path, org.elasticsearch.client: X-Pack-Transport: 5.5.0 ต้องได้รับการแนะนำ เวอร์ชันจะต้องเหมือนกับรุ่น ES และคุณสามารถใช้ TransportClient ด้วยตัวเองได้ดังนี้
@ComponentPublic คลาส Esconfig {@bean Public TransportClient TransportClient () พ่น unknownhostexception {transportClient client = ใหม่ preBuiltxPackTransportClient (settings.builder (). builder ("cluster.name", "docker-cluster"). .AddTransportaddress (ใหม่ InetSocketTransportaddress (Inetaddress.getByName ("0.0.0.0"), 9300)); ไคลเอนต์ส่งคืน; -นี่เป็นวิธีแก้ปัญหาที่เร็วกว่าที่เลือกเพราะฉันไม่ต้องการไปที่ Docker เพื่อจัดการกับปลั๊กอิน X-Path หากไม่จำเป็นฉันไม่จำเป็นต้องสัมผัสบางสิ่งใน ES ในเวลานั้น
MQ จะบันทึกข้อมูลคลาสของข้อความทำให้ deserialized ล้มเหลว
RabbitMQ ในชื่อไม่เคยถูกกล่าวถึงเพราะมันถูกใช้เป็นคิวข้อความ เมื่อข้อมูลเปลี่ยนแปลงรหัสข้อความจะถูกส่งไปยัง MQ และผู้บริโภคในบริการค้นหาจะถูกใช้
ปัญหาคือเมื่อข้อความถูกโยนลงไปใน MQ มันจะถูกห่อหุ้มไว้ในวัตถุของตัวเองซึ่งทำให้ rabtemplate.receiveandConvert ล้มเหลวเพราะข้อความจะส่งข้อมูลแพ็คเกจวัตถุ ในความสิ้นหวังผู้บริโภคสามารถรับไบต์ข้อความโดยตรงในคิวและแปลงรูปแบบ JSON เป็นวัตถุโดยใช้วิธี ObjectMapper.readValue
การกำหนดค่า Gradle สามารถใช้ -dloader.main เพื่อระบุฟังก์ชั่นเริ่มต้น
เป็นเพราะ MQ ได้รับการแนะนำว่าบริการค้นหาจำเป็นต้องเริ่มต้นผู้บริโภค วิธีการคือการใช้แอปพลิเคชันที่ไม่ได้เริ่มต้นบริการเว็บและกำหนดค่า SimpleMessAgelistenerContainer และ MessageListenerAdapter ดังนี้:
@Bean SimpleMessAgelistenerContainer Container (ConnectionFactory ConnectionFactory, MessageListenerAdapter ListenerAdapter, คุณสมบัติ MQConfig) {SimpleMessageListenerContainer คอนเทนเนอร์ = ใหม่ SimpleMessAgelistenerContainer (); container.SetConnectionFactory (ConnectionFactory); container.setqueuenames (properties.getqueuename ()); container.setMessageListener (ListenerAdapter); ส่งคืนคอนเทนเนอร์; } @Bean MessageListenerAdapter ListenerAdapter () {MessageListenerAdapter ListenerAdapter = New MessageListenerAdapter (itemConsumer, "กิน"); ส่งคืนผู้ฟัง; - ปัญหาคือเมื่อการกำหนดค่า Gradle ฉันค้นหาเป็นเวลานานเพื่อให้แพ็คเกจ JAR สร้างขึ้นด้วย -dloader.main ที่ระบุเพื่อระบุแอปพลิเคชันเริ่มต้น การแก้ปัญหามีดังนี้:
เพิ่มในไฟล์ xxx.gradle
bootjar {manifest {แอตทริบิวต์ 'main-class': 'org.springframework.boot.load.load.propertieslauncher'}}}ในโครงการ Springboot 1.5.9 คุณต้องระบุแอปพลิเคชันเริ่มต้นและจำเป็นต้องเพิ่ม
Springboot {layout = "zip"}วิธีการตรวจสอบว่ามันมีผลหรือไม่คือการคลายซิปแพ็คเกจ JAR โดยตรงหลังจากสร้างและตรวจสอบใน XXX (ชื่อโครงการ) /meta-info/manifest.mf
ชั้นหลัก: org.springframework.boot.load.propertieslauncher
จากนั้นถูกต้องถ้า
คลาสหลัก: org.springframework.boot.loader.jarlauncher
ระดับเริ่มต้นในไฟล์จะยังคงเริ่มต้น
ES ไม่สามารถแก้ไขการแมปของดัชนีได้
เนื่องจากมันใช้ฟังก์ชั่นการค้นหาข้อความของ ES จึงมีผลการค้นหาที่ไม่น่าพอใจมากมายในแอปพลิเคชันจริงเช่นการค้นหา "โต๊ะทำงาน" และเป็นไปไม่ได้ที่จะค้นหาเนื้อหาเช่น "โต๊ะคอมพิวเตอร์/โต๊ะทำงาน" และตาราง XX อื่น ๆ มีหลายกรณีด้วยวิธีนี้ ดังนั้นจึงมีการเพิ่มพจนานุกรมคำพ้องความหมายและไม่ใช้พจนานุกรมคำศัพท์ IK_SMART ในฟิลด์ที่ต้องใช้การแบ่งส่วนคำดังนั้นการแมปของบางฟิลด์จะต้องเปลี่ยนเป็น
// analyzer เป็นชื่อ segmenter คำของตัวเอง @field (type = fieldType.text, index = true, analyzer = "synconym") คำอธิบายสตริงส่วนตัว;
เนื่องจากการแมป ES 'ไม่สามารถแก้ไขได้คุณสามารถสร้างการแมปใหม่ด้วยตนเองเท่านั้นจากนั้นใช้เมธอด Reindex เพื่อย้อนกลับข้อมูล (ES5.X มาพร้อมกับ Reindex API) มีวิธีการออนไลน์ผ่านนามแฝง ในสถานการณ์การปรับเปลี่ยนบางอย่างคุณสามารถปรับเปลี่ยนการแมปได้อย่างราบรื่นโดยไม่ต้องรีสตาร์ท/ปรับใช้แอปพลิเคชัน คุณสามารถสอบถามและเข้าใจรายละเอียดได้
ข้างต้นเกือบจะเป็นข้อผิดพลาดที่ได้รับการสัมผัสจากบริการค้นหา หลายคนใช้เวลาและพลังงานมากในการแก้ปัญหา ฉันหวังว่ามันจะเป็นค่าอ้างอิงสำหรับรายการนี้ ในอนาคตจะมีการเพิ่มประสิทธิภาพบางอย่างในบริการค้นหาและจะได้รับการปรับปรุงอย่างช้าๆ ฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น