การใช้งาน Java ของเทคโนโลยี BigPipe ของ Facebook
JPIPE ถูกนำไปใช้ผ่านแท็กที่กำหนดเองดังนั้นจึงมีการบุกรุกเข้าสู่รหัสแบ็กเอนด์เป็นศูนย์
HTML เป็นฟังก์ชั่นที่ทำให้หน้าเบื้องหน้าเสร็จสมบูรณ์ในขณะที่แท็กที่กำหนดเองสามารถดำเนินการบางอย่างในพื้นหลังได้
ส่วนใหญ่ใช้กับ:
| พิมพ์ | จำนวนคำขอ | ความดันฝั่งเซิร์ฟเวอร์ | ประสบการณ์ผู้ใช้ | ความเร็วในการโหลดหน้าเว็บ | ลำดับการโหลดโมดูล | ความยากลำบากในการบรรลุเป้าหมาย | ความยากลำบากในการบำรุงรักษาหลัง |
|---|---|---|---|---|---|---|---|
| สามัญ | 1 | เล็ก | ความแตกต่าง | ช้า | คำสั่งซื้อเอกสาร | เรียบง่าย | โดยทั่วไป |
| อาแจ็กซ์ | มากมาย | ใหญ่ | ดี | เร็ว | ไม่แน่นอน | ความยากลำบาก | ความยากลำบาก |
| bigpipe แบบเธรดเดี่ยว | 1 | เล็ก | ดี | ช้า | ปรับแต่ง | โดยทั่วไป | โดยทั่วไป |
| bigpipe มัลติเธรด | 1 | ทั่วไป (เกิดจากพูลด้าย) | ดี | เร็วที่สุด | ไม่แน่นอน | ยากที่สุด | โดยทั่วไป |
| คุณสมบัติ | พิมพ์ | จำเป็นหรือไม่ | ค่าเริ่มต้น | อธิบาย | อธิบาย |
|---|---|---|---|---|---|
| ขนาดหลัก | int | เลขที่ | -1 | จำนวนเธรดหลัก | จำนวนขั้นต่ำของเธรดที่ไม่ได้ใช้งานจำนวนเธรดขั้นต่ำที่จะอยู่รอดต่อไป |
| ขนาดสูงสุด | int | เลขที่ | 1024 | จำนวนเธรดสูงสุด | JPIPE สามารถสร้างจำนวนเธรดสูงสุดที่ใช้ในการประมวลผล pagelets |
| ขนาดคิว | int | เลขที่ | 1024 | จำนวนคอลัมน์ร่วมรอสูงสุด | การร้องขอพร้อมกันมากกว่าขนาดสูงสุดและจะถูกใส่เข้าไปในคิวและรอ |
| เก็บรักษาไว้ | ยาว | เลขที่ | 60000 | เวลาว่างสูงสุด (MS) | หากจำนวนเธรดเกินขนาดหลักจะมีการรีไซเคิลจนกว่าจำนวนเธรดจะเท่ากับขนาดแกน |
| ก่อนเริ่มต้น-ธรณีประตู | บูลีน | เลขที่ | เท็จ | เปิดพูลเธรดร้อน | ไม่ว่าจะเป็นเธรดขนาดหลักก่อน |
| คุณสมบัติ | พิมพ์ | จำเป็นหรือไม่ | ค่าเริ่มต้น | อธิบาย | อธิบาย |
|---|---|---|---|---|---|
| async | บูลีน | เลขที่ | จริง | ไม่ว่าจะดำเนินงาน pagelet แบบอะซิงโครนัส |
| คุณสมบัติ | พิมพ์ | จำเป็นหรือไม่ | ค่าเริ่มต้น | อธิบาย | อธิบาย |
|---|---|---|---|---|---|
| ทำให้ขุ่นเคือง | สาย | ใช่ | รหัสเอกสาร HTML | ||
| ถั่ว | สาย | ใช่ | ชื่อถั่วฤดูใบไม้ผลิ | ||
| วาจา | สาย | ใช่ | พารามิเตอร์ตัวแปร | ||
| URI | สาย | เลขที่ | พารามิเตอร์ URI | ||
| jsmethod | สาย | เลขที่ | JP.View | ฟังก์ชั่น JS ที่ห่อข้อมูล |
JpipeThreadPoolFactoryBean <? xml version = " 1.0 " encoding = " UTF-8 " ?>
< beans xmlns = " http://www.springframework.org/schema/beans "
xmlns : xsi = " http://www.w3.org/2001/XMLSchema-instance "
xsi : schemaLocation = " http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd " >
< bean class = " top.ylonline.jpipe.spring.JpipeSpringFactoryBean " />
< bean id = " pool-1 " class = " top.ylonline.jpipe.threadpool.common.Pool " >
< property name = " coreSize " value = " -1 " />
< property name = " maxSize " value = " 20 " />
< property name = " preStartAllCoreThreads " value = " false " />
< property name = " keepAlive " value = " 12000000 " />
< property name = " queueSize " value = " 500 " />
</ bean >
<!-- 工场模式 -->
< bean class = " top.ylonline.jpipe.threadpool.util.JpipeThreadPoolFactoryBean " >
< property name = " pool " ref = " pool-1 " />
</ bean >
<!-- 或者
<bean class="top.ylonline.jpipe.threadpool.util.JpipeThreadPoolFactoryBean">
<property name="pool">
<bean class="top.ylonline.jpipe.threadpool.common.Pool">
<property name="coreSize" value="4"/>
<property name="maxSize" value="10"/>
<property name="preStartAllCoreThreads" value="true"/>
<property name="keepAlive" value="60000"/>
<property name="queueSize" value="500"/>
</bean>
</property>
</bean>
-->
</ beans >JpipeThreadPoolBuilder <? xml version = " 1.0 " encoding = " UTF-8 " ?>
< beans xmlns = " http://www.springframework.org/schema/beans "
xmlns : xsi = " http://www.w3.org/2001/XMLSchema-instance "
xsi : schemaLocation = " http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd " >
< bean class = " top.ylonline.jpipe.spring.JpipeSpringFactoryBean " />
<!-- builder 模式 -->
< bean id = " jpipeThreadPoolBuilder " class = " top.ylonline.jpipe.threadpool.util.JpipeThreadPoolBuilder " >
< property name = " pool " >
< bean class = " top.ylonline.jpipe.threadpool.common.Pool " >
< property name = " coreSize " value = " 1 " />
< property name = " maxSize " value = " 1 " />
< property name = " preStartAllCoreThreads " value = " true " />
< property name = " keepAlive " value = " 1 " />
< property name = " queueSize " value = " 1 " />
</ bean >
</ property >
</ bean >
< bean id = " jpipeThreadPool-3 " factory-bean = " jpipeThreadPoolBuilder " factory-method = " build " />
</ beans > @ Bean
public JpipeSpringFactoryBean jpipeSpringFactoryBean (){
return new JpipeSpringFactoryBean ();
}
@ Bean
public JpipeThreadPoolExecutor jpipeThreadPoolExecutor () {
Pool pool = new Pool ();
pool . setCoreSize ( 10 );
pool . setMaxSize ( 1024 );
pool . setPreStartAllCoreThreads ( true );
pool . getKeepAlive ( 60000 );
pool . getQueueSize ( 512 );
// return new EagerThreadPool().getExecutor(pool);
return new JpipeThreadPoolBuilder ( pool ). build ();
}ผ่านสปริงบูทสตาร์ทเตอร์
< dependency >
< groupId >top.ylonline.jpipe</ groupId >
< artifactId >jpipe-spring-boot-starter</ artifactId >
< version >${version}</ version >
</ dependency > jpipe :
# enabled: true
pool :
pre-start-all-core-threads : true
core-size : -1
max-size : 20
queue-size : 10
keep-alive : 10000 ใช้ @Service ของ Spring เพื่อกำหนด pagelet เพื่อใช้วิธี doexec ของอินเทอร์เฟซ PageletBean
@ Service ( "testPagelet1" )
public class PageletServiceTest implements PageletBean {
@ Override
public Map < String , Object > doExec ( final Map < String , String > params ) {
Map < String , Object > data = new HashMap <>( params );
try {
TimeUnit . MILLISECONDS . sleep ( new Random (). nextInt ( 5000 ));
} catch ( InterruptedException e ) {
e . printStackTrace ();
}
return data ;
}
}jpipe.core.js
; ( function ( root , factory ) {
if ( typeof exports === 'object' ) {
module . exports = exports = factory ( ) ;
} else if ( typeof define === 'function' && define . amd ) {
define ( [ ] , factory ) ;
} else {
root . JP = factory ( ) ;
}
} ( this , function ( ) {
var JP = JP || ( function ( window ) {
return {
view : function ( json ) {
var id = json [ 'id' ] ;
document . getElementById ( id ) . innerHTML = json [ 'html' ] ;
}
} ;
} ( window ) ) ;
return JP ;
} ) ) ;<%@ taglib prefix="jp" uri="http://java.yl-online.top/jsp/jpipe" %></body> เพื่อให้การแสดงผลของหน้าจอแรก DOM จะไม่ถูกบล็อก < %@ page contentType="text/html;charset=UTF-8" trimDirectiveWhitespaces="true" % >
< %@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" % >
< %@ taglib prefix="jp" uri="http://java.yl-online.top/jsp/jpipe" % >
< c:set var =" ctx " value =" ${pageContext.request.contextPath} " />
< html lang =" en " >
< head >
< title > index </ title >
< meta http-equiv =" Content-Type " content =" text/html; charset=UTF-8 " />
< meta name =" viewport " content =" width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no " >
< script type =" text/javascript " src =" ${ctx}/resources/jpipe.core.js " > </ script >
</ head >
< body >
< h1 > index </ h1 >
< div id =" pagelet1 " > </ div >
< div id =" pagelet2 " > </ div >
< jp:pipe >
< jp:pagelet domid =" pagelet1 " bean =" testPagelet1 " var =" item " uri =" id=123&name=forever杨" >
< h1 > jspbody support </ h1 >
< p > ${item.id} </ p >
</ jp:pagelet >
< jp:pagelet domid =" pagelet2 " bean =" testPagelet2 " var =" item2 " uri =" id=456&name=forever杨2 " >
< h1 > jspbody support </ h1 >
< p > ${item2.name} </ p >
</ jp:pagelet >
</ jp:pipe >
</ body >
</ html >ไม่: ปรับใช้กับคอนเทนเนอร์เช่น Tomcat และ Jetty
@ Configuration
public class MvcWevConfig {
@ Resource
private freemarker . template . Configuration configuration ;
@ PostConstruct
public void setConfiguration () {
Version version = freemarker . template . Configuration . getVersion ();
DefaultObjectWrapper wrapper = new DefaultObjectWrapperBuilder ( version ). build ();
this . configuration . setSharedVariable ( "jp" , new FmHashModel ( wrapper ));
}
} < #-- < #assign pipe="top.ylonline.jpipe.freemarker.tag.PipeTag"?new() /> -- >
< #-- < #assign pagelet="top.ylonline.jpipe.freemarker.tag.PageletTag"?new() /> -- >
< html lang =" en " >
< head >
< title > index </ title >
< meta http-equiv =" Content-Type " content =" text/html; charset=UTF-8 " />
< meta name =" viewport " content =" width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no " >
< script type =" text/javascript " src =" jpipe.core.js " > </ script >
</ head >
< body >
< h1 > index </ h1 >
< div id =" pagelet1 " > </ div >
< div id =" pagelet2 " > </ div >
< @jp.pipe >
< @jp.pagelet domid="pagelet1" bean="testPagelet1" var="item" uri="id=123&name=forever杨" >
< h1 > testPagelet1 jspbody support </ h1 >
< p > ${item.id} </ p >
</ @jp.pagelet >
< @jp.pagelet domid="pagelet2" bean="testPagelet2" var="item2" uri="id=456&name=forever杨2" >
< h1 > testPagelet2 jspbody support </ h1 >
< p > ${item2.name} </ p >
</ @jp.pagelet >
</ @jp.pipe >
</ body >
</ html > < #assign pipe="top.ylonline.jpipe.freemarker.tag.PipeTag"?new() />
< #assign pagelet="top.ylonline.jpipe.freemarker.tag.PageletTag"?new() />
< html lang =" en " >
< head >
< title > index </ title >
< meta http-equiv =" Content-Type " content =" text/html; charset=UTF-8 " />
< meta name =" viewport " content =" width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no " >
< script type =" text/javascript " src =" jpipe.core.js " > </ script >
</ head >
< body >
< h1 > index </ h1 >
< div id =" pagelet1 " > </ div >
< div id =" pagelet2 " > </ div >
< @jp.pipe >
< @jp.pagelet domid="pagelet1" bean="testPagelet1" var="item" uri="id=123&name=forever杨" >
< h1 > testPagelet1 jspbody support </ h1 >
< p > ${item.id} </ p >
</ @jp.pagelet >
< @jp.pagelet domid="pagelet2" bean="testPagelet2" var="item2" uri="id=456&name=forever杨2" >
< h1 > testPagelet2 jspbody support </ h1 >
< p > ${item2.name} </ p >
</ @jp.pagelet >
</ @jp.pipe >
</ body >
</ html >FTL รองรับการใช้แท็ก JSP หากโครงการของคุณไม่ได้ใช้เทมเพลต JSP ไม่แนะนำ เนื่องจากแท็ก JSP ที่กำหนดเองถูกเขียนและดำเนินการในสภาพแวดล้อม JSP จึงจำเป็นต้องมีการแนะนำคอนเทนเนอร์ Servlet ที่รองรับ JSP 1.1 หรือ JSP 1.2 (การปรับใช้คอนเทนเนอร์ Servlet เช่น Tomcat และ Jetty) และ FTL สามารถใช้ในที่ไม่ได้รับบริการและสภาพแวดล้อมเว็บอื่น ๆ
คำอธิบายที่แม่นยำยิ่งขึ้นคือ: แม้ว่าคอนเทนเนอร์ servlet จะไม่มีการสนับสนุน JSP ในเครื่อง แต่คุณยังสามารถใช้ไลบรารีแท็ก JSP ใน Freemarker เพียงตรวจสอบให้แน่ใจว่าแพ็คเกจ javax.servlet.jsp.* สำหรับ JSP เวอร์ชัน 1.2 (หรือใหม่กว่า) มีอยู่ในเว็บแอปพลิเคชัน หากคอนเทนเนอร์ servlet ของคุณรองรับ JSP 1.1 เท่านั้นคุณต้องคัดลอกคลาสหกคลาสต่อไปนี้ (เช่นคุณสามารถแยกออกจากแพ็คเกจ Jar ของ Tomcat 5.x หรือ Tomcat 4.x) ไปยัง Web-inf/classes/... ไดเรกทอรีของเว็บแอปพลิเคชัน: javax.servlet.jsp.tagext.iterationtag javax.servlet.servletContextListener, javax.servlet.servletContextattributelistener, javax.servlet.http.httpsessionattributelistener, javax.servlet.http.httpsessionListener อย่างไรก็ตามโปรดทราบว่าเนื่องจากคอนเทนเนอร์รองรับ JSP 1.1 โดยปกติจะใช้เวอร์ชันก่อนหน้าก่อนหน้า Servlet 2.3 ผู้ฟังเหตุการณ์อาจไม่ได้รับการสนับสนุนดังนั้น JSP 1.2 Tag Library เพื่อลงทะเบียนผู้ฟังเหตุการณ์จะทำงานได้ตามปกติ
เวลากด: JSP ได้รับการเผยแพร่ในเวอร์ชัน 2.3
ใช้ <#assign jp=JspTaglibs["http://java.yl-online.top/jsp/jpipe"] /> เพื่อแนะนำแท็ก jsp ที่กำหนดเอง
< #assign jp=JspTaglibs["http://java.yl-online.top/jsp/jpipe"] />
< html lang =" en " >
< head >
< title > index </ title >
< meta http-equiv =" Content-Type " content =" text/html; charset=UTF-8 " />
< meta name =" viewport " content =" width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no " >
< script type =" text/javascript " src =" jpipe.core.js " > </ script >
</ head >
< body >
< h1 > index </ h1 >
< div id =" pagelet1 " > </ div >
< div id =" pagelet2 " > </ div >
< @jp.pipe >
< @jp.pagelet domid="pagelet1" bean="testPagelet1" var="item" uri="id=123&name=forever杨" >
< h1 > testPagelet1 support </ h1 >
< p > ${item.id} </ p >
</ @jp.pagelet >
< @jp.pagelet domid="pagelet2" bean="testPagelet2" var="item2" uri="id=456&name=forever杨2" >
< h1 > testPagelet2 support </ h1 >
< p > ${item2.name} </ p >
</ @jp.pagelet >
</ @jp.pipe >
</ body >
</ html > การพึ่งพา maven
<!-- undertow 部署 -->
< dependency >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-undertow</ artifactId >
</ dependency >
<!-- undertow 部署 -->
< dependency >
< groupId >javax.servlet.jsp</ groupId >
< artifactId >javax.servlet.jsp-api</ artifactId >
< version >2.3.3</ version >
</ dependency >เนื่องจากคอนเทนเนอร์เช่น undertow ไม่มีสภาพแวดล้อม JSP-API พวกเขาจำเป็นต้องพึ่งพาแพ็คเกจ javax.servlet.jsp-api และในเวลาเดียวกันพวกเขาจำเป็นต้องกำหนดค่า classpathtlds ของ freemarker ผ่าน taglibfactory หากไม่มีการกำหนดค่านี้จะมีการรายงานข้อผิดพลาด: freemarker.ext.jsp.taglibfactory $ taglibgettingException: ไม่พบ TLD สำหรับ "http://java.yl-online.top/jsp/jpipe" JSP Taglib uri (TLD-S ถูกค้นหาตามข้อกำหนดของ JSP 2.2 ในการตั้งค่าการพัฒนา-และการฝังตัวแบบฝังตัวคุณอาจต้องใช้ "MetaInftldSources" และ "classpathtlds" freemarker.ext.servlet.freeMarkerservlet
การกำหนดค่า
@ Configuration
public class MvcWevConfig {
@ Resource
private FreeMarkerConfigurer freeMarkerConfigurer ;
@ PostConstruct
public void loadClassPathTlds () {
List < String > classpathTlds = new ArrayList <>();
classpathTlds . add ( "/META-INF/Jpipe.tld" );
freeMarkerConfigurer . getTaglibFactory (). setClasspathTlds ( classpathTlds );
}
}การพึ่งพา maven
<!-- 外部 Tomcat 部署 -->
< dependency >
< groupId >javax.servlet</ groupId >
< artifactId >javax.servlet-api</ artifactId >
< scope >provided</ scope >
</ dependency >
< dependency >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-tomcat</ artifactId >
< scope >provided</ scope >
</ dependency >
< dependency >
< groupId >org.apache.tomcat.embed</ groupId >
< artifactId >tomcat-embed-jasper</ artifactId >
< scope >provided</ scope >
</ dependency >
<!-- 外部 Tomcat 部署 -->เนื่องจากมีสภาพแวดล้อม JSP-API ใน Tomcat และ Jetty อยู่แล้วจึงไม่จำเป็นต้องพึ่งพาแพ็คเกจ javax.servlet.jsp-api ที่นี่อีกต่อไป