ก่อนที่จะใช้แอสเซมบลีเพื่อบรรจุโครงการ Microservices Springboot ฉันอยากจะพูดคุยเกี่ยวกับวิธีการปรับใช้ทั่วไปหลายวิธีสำหรับโครงการ SpringBoot ในปัจจุบัน
ใช้คอนเทนเนอร์ Docker เพื่อปรับใช้สร้างแอปพลิเคชันของ Springboot ลงในอิมเมจนักเทียบท่าแล้วเริ่มภาพผ่านคอนเทนเนอร์ วิธีนี้สะดวกมากเมื่อต้องการแอปพลิเคชันขนาดใหญ่และแอปพลิเคชันส่วนขยาย มันเป็นโซลูชันการปรับใช้ระดับอุตสาหกรรมในปัจจุบัน แต่ต้องใช้เทคโนโลยีระบบนิเวศของ Docker
ใช้ FATJAR เพื่อปรับใช้และเริ่มต้นโดยตรงซึ่งเป็นวิธีการปรับใช้แอปพลิเคชันอย่างง่ายสำหรับผู้เริ่มต้นหรือสถานการณ์ขนาดเล็กมาก
บทความนี้ส่วนใหญ่เป็นโซลูชั่นบรรจุภัณฑ์ที่เป็นมิตรมากขึ้นสำหรับวิธีการปรับใช้ครั้งที่สองซึ่งคือการทำให้การจัดการการปรับใช้ง่ายขึ้น วิธีแรกอาจเขียนในบล็อกของฉันในอนาคต
1. ทำไม Springboot ควรบรรจุในบริการ?
เมื่อเร็ว ๆ นี้ฉันเห็นทีมงานโครงการ พวกเขาใช้ Springboot เพื่อพัฒนาโครงการและสร้างปฏิสัมพันธ์กับทีมปฏิบัติการและการบำรุงรักษาซึ่งเป็นสปริงบูต Fatjar ยิ่งไปกว่านั้นแพ็คเกจดั้งเดิมนี้ไม่ต้องสงสัยเลยว่าเป็นอันตรายถึงชีวิตอย่างไม่ต้องสงสัยสำหรับบุคลากรด้านการดำเนินงานและการบำรุงรักษาใน บริษัท พัฒนาโครงการแบบดั้งเดิม หลังจากส่งมอบโครงการไฟล์การกำหนดค่าทั้งหมดจะถูกซ่อนอยู่ใน JAR และการแก้ไขไฟล์การกำหนดค่าสำหรับสภาพแวดล้อมที่แตกต่างกันกลายเป็นสิ่งที่ยากมาก ดังนั้นเมื่อเราแนะนำเทคโนโลยีใหม่ ๆ ใน บริษัท เราต้องพิจารณาวิธีการให้บริการที่มุ่งเน้นและวิศวกรรม หากเราอ้างถึงกรอบทางเทคนิคเท่านั้นเราอาจต้องเพิ่มการพึ่งพาเพียงไม่กี่ครั้งและอ่าน API และเขียนรหัสสองสามบรรทัดเพื่อเรียกใช้
เพื่อแก้ไขปัญหาข้างต้นเราจำเป็นต้องมุ่งเน้นการบริการและเชิงวิศวกรรมและเราจำเป็นต้องแก้ปัญหาสองอย่างโดยประมาณ:
เปิดใช้งาน SpringBoot เพื่อโหลดไฟล์การกำหนดค่านอกขวด
จัดเตรียมสคริปต์เริ่มต้นตามบริการซึ่งโดยปกติจะเป็นเชลล์หรือค้างคาวภายใต้ Windows ด้วยสคริปต์บริการแอปพลิเคชันของ Springboot คุณสามารถเริ่มต้นและหยุดแอปพลิเคชัน Springboot ได้
2. แผนผังโครงสร้างแอปพลิเคชัน Springboot แพคเกจ
ที่นี่ก่อนอื่นเราจะดูการเรนเดอร์หลังจากใช้แอสเซมบลีเพื่อแพ็คเกจบริการ Springboot
3. ขั้นตอนสำคัญสำหรับบรรจุภัณฑ์บริการ
ด้านล่างนี้เป็นขั้นตอนโดยละเอียดสำหรับการบรรจุสปริงบูท
3.1 เพิ่มปลั๊กอินแพ็คเกจแอสเซมบลี
<Plugin> <ArtIfactId> maven-assembly-plugin </artifactid> <sersion> 3.0.0 </เวอร์ชัน> <การกำหนดค่า> <scriptors> <scriptor> SRC/Main/Assembly/Assembly.xml </descriptor> </descriptors> <เป้าหมาย> Single </sent> </solor> </Execution> </Executions> </plugin>
จากรหัสข้างต้นฉันได้ใส่การกำหนดค่าแอสเซมบลีในไดเรกทอรีหลัก นี่เป็นนิสัยและคุณไม่สามารถวางไว้ที่นี่ นี่คือแผนภาพโครงสร้างทั่วไปของการประกอบในโครงการ:
3.2 Assembly.xml การกำหนดค่า
การกำหนดค่าของแอสเซมบลีนั้นคล้ายกับการกำหนดค่าต่อไปนี้ซึ่งไม่มีอะไรมากไปกว่าสคริปต์บริการบรรจุภัณฑ์, ขวด, ไฟล์การกำหนดค่า ฯลฯ จากรหัสต่อไปนี้คุณจะพบว่าแอสเซมบลีได้พิมพ์ไฟล์การกำหนดค่าภายใต้การกำหนดค่า
<Sembly> <id> 1.0 </id> <formats> <pormat> tar.gz </format> </formats> <filetes> <fileSet> <fileSet> <Src/Main/Assembly/Bin </Directory> <OutputDirectory> <Irectory> SRC/Main/Assembly/config </directory> <putputDirectory> config </outputDirectory> <s FileMode> 0644 </fileMode> </fileSet> <fileset> <Ictory> เป้าหมาย </ไดเรกทอรี> <outputDirectory> <Irectory> SRC/Main/Resources </directory> <putputDirectory> บันทึก </utputDirectory> <S FileMode> 0755 </fileMode> <EcalUDES> <EXCLUDE> **/*</exclude> </excludes>
3.3 การเขียนสคริปต์บริการ
ตอนนี้เขียนสคริปต์สำหรับสภาพแวดล้อม Linux
คนแรก: start.sh startup script
#!/bin/bashserver_name = 'spring-vue'# jar name jar_name = 'springboot-vue.jar'cd `dirname $ 0`bin_dir =` pwd`cd ..deploy_dir = `pwd`conf_dir = $ deploy_dir/config config/application.properties | tr -d '/r'`# รับหมายเลขพอร์ตของแอปพลิเคชันเซิร์ฟเวอร์ _port = `sed -nr'/พอร์ต: [0-9]+/s /.* พอร์ต:+([0-9]+).*// 1/p 'config/application.yml`pids =` ps -f | Grep Java | grep "$ conf_dir" | awk '{พิมพ์ $ 2}' `ถ้า [" $ 1 "=" สถานะ "]; จากนั้นถ้า [-n "$ pids"]; จากนั้นสะท้อน "$ server_name กำลังทำงานอยู่ ... !" echo "PID: $ pids" ออก 0 ELELS ECHO "$ server_name หยุด" ออก 0 fifiif [-n "$ pids"]; จากนั้น echo "ข้อผิดพลาด: $ server_name เริ่มแล้ว!" echo "pid: $ pids" ออก 1fiif [-n "$ server_port"]; จากนั้น server_port_count = `netstat -tln | grep $ server_port | wc -l` ถ้า [$ server_port_count -gt 0]; จากนั้น echo "ข้อผิดพลาด: พอร์ต $ server_name $ server_port ใช้ไปแล้ว!" ออก 1 fifilogs_dir = $ deploy_dir/logsif [! -d $ logs_dir]; จากนั้น mkdir $ logs_dirfistdout_file = $ logs_dir/stdout.logjava_opts = "-djava.awt.headless = true -djava.net.preferipv4stack = true" java_debug_opts = "" ถ้า "$ 1" จากนั้น java_debug_opts = "-xdebug -xnoagent -djava.compiler = none -xrunjdwp: การขนส่ง = dt_socket, ที่อยู่ = 8000, เซิร์ฟเวอร์ = y, suspend = n" fijava_jmx_opts = "" ถ้า " จากนั้น java_jmx_opts = "-dcom.sun.management.jmxremote.port = 1099 -dcom.sun.management.jmxremote.ssl = false -dcom.sun.management.jmxremote.authenticate = False" Fijava_mem_opts grep -i 64 -bit`if [-n "$ bits"]; จากนั้น java_mem_opts = "-server -xmx512m -xms512m -xmn256m -xx: permsize = 128m -xss256k -xx:+disablexplicitgc -xx:+useconconcmarke -xx: LargePagesizeIzeInbytes = 128m -xx:+usefastaccessormethods -xx:+usecmsinitiatingoccupancyOnly -xx: cmsinitiatingoccupancyfraction = 70 "else java_mem_opts =" -server -xms512m - -xx:+USEPRALLEGC "FICONFIG_FILES =" -DLOGGING.PATH = $ logs_dir -dlogging.config = $ conf_dir/log4j2.xml -dspring.config.location = $ conf_dir/application.properties $ java_mem_opts $ java_debug_opts $ java_jmx_opts $ config_files -jar $ deploy_dir/lib/$ jar_name> $ stdout_file 2> & 1 & count = 0 ในขณะที่ [count -lt 1]; Do echo -e "./c" sleep 1 ถ้า [-n "$ server_port"]; จากนั้นนับ = `netstat -an | grep $ server_port | wc -l` else count = `ps -f | Grep Java | grep "$ deploy_dir" | awk '{พิมพ์ $ 2}' | wc -l` fi ถ้า [$ count -gt 0]; จากนั้นทำลาย fidonecho "ตกลง!" pids = `ps -f | Grep Java | grep "$ deploy_dir" | awk '{print $ 2}' `echo" pid: $ pids "echo" stdout: $ stdout_file "กรณีการใช้สคริปต์:# เริ่มแอปพลิเคชัน/start.sh# เริ่มต้นในโหมดดีบัก/start debug# เริ่มงาน $ 0`bin_dir = `pwd`cd ..deploy_dir =` pwd`conf_dir = $ deploy_dir/configserver_name = $ deploy_dirpids = `ps -ef | Grep Java | grep "$ conf_dir" | awk '{พิมพ์ $ 2}' `ถ้า [-z" $ pids "]; จากนั้น echo "ข้อผิดพลาด: $ server_name ไม่ได้เริ่มต้น!" ออกจาก 1fiif ["$ 1"! = "ข้าม"]; จากนั้น $ bin_dir/dump.shfiecho -e "หยุด $ server_name .../c" สำหรับ PID ใน $ pids; Do Kill $ pid> /dev /null 2> & 1donecount = 0 ในขณะที่ [$ count -lt 1]; Do echo -e "./c" sleep 1 count = 1 สำหรับ pid ใน $ pids; ทำ pid_exist = `ps -f -p $ pid | grep java` ถ้า [-n "$ pid_exist"]; จากนั้นนับ = 0 break fi doingonecho "ตกลง!" echo "PID: $ pids"สคริปต์เริ่มต้นสำหรับสภาพแวดล้อม Windows:
Echo Offset App_name = Springboot -vue.jarset config = -dlogging.path = ../logs -dlogging.config = ../config/log4j2.xml -dspring.config.location = ../config/application.yml set debug_opts = ถ้า "" -xloggc: ../ logs/gc.log -verbose: gc -xx:+printgcdetails -xx:+heapdumponoutofmemoryerror -xx: heapdumppath = ../logs goto debug) ตั้ง jmx_opts = ถ้า ""%1 " -dcom.sun.management.jmxremote -dcom.sun.management.jmxremote.port = 9888 -dcom.sun.management.jmxremote.ssl = false -dcom.sun.management.jmxremote.authenticate = Feste Goto Jmx) -xmx512m -server%debug_opts%jmx_opts%config%-jar ../lib/%App_name%Goto End: debugecho "debug" java -xms512m -xmx512m -server%debug_opts -XMS512M -XMX512M -Server%JMX_OPTS%%config%-jar ../lib/%App_name%Goto End: endpause
สำหรับโครงการ Springboot ที่แตกต่างกันคุณจะต้องแก้ไขสคริปต์อย่างเหมาะสมเท่านั้น เพื่อประหยัดพื้นที่ฉันจะไม่แสดงรายการสคริปต์อื่น ๆ ที่นี่ คุณสามารถอ้างถึงตัวอย่างที่ฉันส่ง: https://github.com/shalousun/springboot-vue.git
หมายเหตุ: สคริปต์ด้านบนอ้างอิงจากเจ้าหน้าที่ Dubbo ในความเป็นจริงมันยังคล้ายกับการก่อสร้างที่มีน้ำหนักเบาของโครงการ Dubbo
4. การประมวลผลเส้นทางเข้าสู่ระบบหลังจากบรรจุภัณฑ์
ในรูปในส่วนที่สองคุณจะเห็นว่าบันทึกแอปพลิเคชันที่บรรจุโดยทั่วไปจะส่งออกไปยังไดเรกทอรีบันทึก อย่างไรก็ตามสำหรับแพลตฟอร์มระบบที่แตกต่างกันแม้ว่าเส้นทางเอาต์พุตบันทึกที่กำหนดค่าจะเหมือนกันพวกเขาอาจไม่จำเป็นต้องเป็นเอาต์พุตไปยังบันทึกในตอนท้าย หลังจากการทดสอบไม่มีปัญหาในการใช้เส้นทางบันทึกสัมพัทธ์ในแพลตฟอร์ม Windows ../บันทึก แต่สำหรับการใช้เส้นทางสัมพัทธ์ในระบบ Linux ไม่สามารถส่งออกไปยังบันทึกได้ ดังนั้นจึงขอแนะนำให้เขียนเส้นทางสัมบูรณ์ในแพลตฟอร์ม Linux อย่างไรก็ตามในสคริปต์ที่ฉันให้ไว้ให้ตั้งค่าเส้นทางไปยังบันทึกเอาต์พุต
-dlogging.path = ../logs
ดังนั้นเมื่อรวมความสามารถในการแยกวิเคราะห์ที่ทรงพลังของ log4j2 คุณสามารถตั้งค่าเส้นทางการบันทึกของ log42:
<property name = "log_home"> $ {sys: logging.path} </porement>อย่างไรก็ตามบันทึกการเข้าถึงสำหรับแอปพลิเคชัน Springboot ดูเหมือนจะใช้เส้นทางสัมบูรณ์ภายใต้ Linux เท่านั้น
# เซิร์ฟเวอร์ configserver: พอร์ต: 8080 undertow: accesslog: เปิดใช้งาน: True Dir:/usr/xxx/logslogging: path:/usr/xxx/logs
แน่นอนว่านักเรียนที่ใช้การกำหนดค่าเพื่อแก้ปัญหาในภายหลังสามารถเตือนให้พวกเขาแก้ไขได้
สรุป:
แผนนี้ไม่ได้นำสิ่งใหม่ ๆ และสคริปต์ส่วนใหญ่อ้างอิงถึงสคริปต์อย่างเป็นทางการของ Dubbo แต่พวกเขาได้ทำการปรับปรุงบางอย่าง แต่ประเด็นสำคัญคือวิธีคิดเกี่ยวกับบริการและวิศวกรรมที่จำเป็นในการใช้เทคโนโลยีนี้ตามสถานการณ์แอปพลิเคชันทางเทคนิคจริง
ด้านบนเป็นโซลูชันบรรจุภัณฑ์บริการที่ใช้สปริงบู๊ตประกอบที่แนะนำโดยตัวแก้ไข ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับทุกคนในเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!