Implementasi Java dari teknologi bigpipe Facebook.
JPIPE diimplementasikan melalui tag khusus, sehingga memiliki nol intrusi ke dalam kode backend.
HTML adalah fungsi yang menyelesaikan halaman latar depan, sementara tag khusus dapat menyelesaikan operasi tertentu di latar belakang.
Terutama berlaku untuk:
| jenis | Jumlah permintaan | Tekanan sisi server | Pengalaman Pengguna | Kecepatan pemuatan halaman web | Pesanan pemuatan modul | Kesulitan untuk dicapai | Kesulitan dalam pasca pemeliharaan |
|---|---|---|---|---|---|---|---|
| biasa | 1 | Kecil | Perbedaan | lambat | Urutan Aliran Dokumen | Sederhana | umumnya |
| Ajax | banyak | besar | Bagus | cepat | tidak pasti | kesulitan | kesulitan |
| Bigpipe tunggal | 1 | Kecil | Bagus | lambat | Menyesuaikan | umumnya | umumnya |
| Bigpipe multithreaded | 1 | Umum (disebabkan oleh kumpulan utas) | Bagus | Tercepat | tidak pasti | Yang paling sulit | umumnya |
| milik | jenis | Apakah itu diperlukan | Nilai default | menjelaskan | menggambarkan |
|---|---|---|---|---|---|
| Ukuran inti | int | TIDAK | -1 | Jumlah utas inti | Jumlah minimum utas idle, jumlah minimum utas yang akan bertahan |
| ukuran maksimal | int | TIDAK | 1024 | Jumlah utas maksimum | JPIPE dapat membuat jumlah maksimum utas yang digunakan untuk memproses pagelet |
| Ukuran antrian | int | TIDAK | 1024 | Hitungan co-kolom menunggu maksimal | Permintaan konkurensi lebih besar dari ukuran maksimal, dan akan dimasukkan ke dalam antrian dan menunggu. |
| Tetap hidup | panjang | TIDAK | 60000 | Waktu idle maksimum (MS) | Jika jumlah utas melebihi ukuran inti, itu akan didaur ulang sampai jumlah utas sama dengan ukuran inti. |
| Pra-start-all-core-threads | Boolean | TIDAK | PALSU | Panaskan kumpulan utas | Apakah akan memulai utas inti-ukuran |
| milik | jenis | Apakah itu diperlukan | Nilai default | menjelaskan | menggambarkan |
|---|---|---|---|---|---|
| async | Boolean | TIDAK | BENAR | Apakah akan menjalankan tugas pagelet secara tidak sinkron |
| milik | jenis | Apakah itu diperlukan | Nilai default | menjelaskan | menggambarkan |
|---|---|---|---|---|---|
| domid | rangkaian | Ya | ID Dokumen HTML | ||
| kacang | rangkaian | Ya | Nama kacang musim semi | ||
| var | rangkaian | Ya | parameter variabel | ||
| Uri | rangkaian | TIDAK | Parameter URI | ||
| jsmethod | rangkaian | TIDAK | JP.View | fungsi JS yang membungkus data |
JpipeThreadPoolFactoryBean Class <? 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 ();
}melalui starter boot-boot
< 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 Gunakan Spring's @Service untuk mendefinisikan pagelet untuk mengimplementasikan metode doexec dari antarmuka 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> sehingga rendering layar pertama DOM tidak akan diblokir. < %@ 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 >TIDAK: Digantikan ke wadah seperti Tomcat dan 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 mendukung penggunaan tag JSP. Jika proyek Anda tidak menggunakan templat JSP, ini tidak disarankan. Karena tag JSP kustom ditulis dan dioperasikan di lingkungan JSP, wadah servlet yang mendukung JSP 1.1 atau JSP 1.2 perlu diperkenalkan (penyebaran wadah servlet seperti Tomcat dan Jetty), dan FTL dapat digunakan di lingkungan non-servlet dan lingkungan web lainnya.
Penjelasan yang lebih akurat adalah: Meskipun wadah servlet tidak memiliki dukungan JSP lokal, Anda juga dapat menggunakan pustaka tag JSP di Freemarker. Pastikan saja bahwa paket javax.servlet.jsp.* Untuk JSP versi 1.2 (atau lebih baru) tersedia di aplikasi web. Jika wadah servlet Anda hanya mendukung JSP 1.1, maka Anda harus menyalin enam kelas berikut (seperti Anda dapat mengekstrak dari paket JAR Tomcat 5.x atau Tomcat 4.x) ke Web-Inf/Kelas/... Direktori Aplikasi Web: javax.servlet.jsp.tagext.iterationTag, javax.servlet.patchx.patchyally.itagey, javax.servlet.patchycyally.itage, javax.servlet.jscats. javax.servlet.servletcontextListener, javax.servlet.servletcontextattributeListener, javax.servlet.http.httpsessionattributeListener, javax.servlet.http.httpsessionlistener. Namun, ketahuilah bahwa karena wadah hanya mendukung JSP 1.1, biasanya menggunakan versi sebelumnya sebelum Servlet 2.3, pendengar acara mungkin tidak didukung, sehingga perpustakaan tag JSP 1.2 untuk mendaftarkan pendengar acara akan bekerja secara normal.
Pada waktu pers: JSP telah dirilis ke versi 2.3
Gunakan <#assign jp=JspTaglibs["http://java.yl-online.top/jsp/jpipe"] /> untuk memperkenalkan tag JSP khusus
< #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 > Ketergantungan 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 >Karena wadah seperti Undertow tidak memiliki lingkungan JSP-API, mereka perlu mengandalkan paket javax.servlet.jsp-API, dan pada saat yang sama, mereka perlu mengkonfigurasi classpathtlds dari freemarker melalui taglibfactory. Tanpa konfigurasi ini, kesalahan akan dilaporkan: freemarker.ext.jsp.taglibfactory $ taglibgettingException: Tidak ada tld yang ditemukan untuk "http://java.yl-online.top/jsp/jpipe" jsp taglib uri. (TLD-S dicari sesuai dengan spesifikasi JSP 2.2. Dalam pengaturan pengembangan- dan embedded-servlet-container, Anda mungkin juga memerlukan "Sumber MetainftldS" dan "ClassPathTlds" Freemarker.Ext.Servlet.FreeMarkerServlet init-params atau properti sistem yang serupa.)
Konfigurasi
@ 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 );
}
}Ketergantungan 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 部署 -->Karena sudah ada lingkungan JSP-API di Tomcat dan Jetty, tidak perlu mengandalkan paket javax.servlet.jsp-api di sini lagi