Реализация Java технологии Bigpipe Facebook.
JPipe реализована с помощью пользовательских тегов, поэтому она имеет нулевое вторжение в код бэкэнда.
HTML - это функция, которая завершает страницу переднего плана, в то время как пользовательские теги могут завершить определенные операции в фоновом режиме.
В основном применимо к:
| тип | Количество запросов | Давление на стороне сервера | Пользовательский опыт | Скорость загрузки веб -страницы | Заказ на загрузку модуля | Трудности достичь | Сложность в пост-техническом обслуживании |
|---|---|---|---|---|---|---|---|
| обычный | 1 | Маленький | Разница | медленный | Заказ потока документов | Простой | в целом |
| Аякс | много | большой | хороший | быстрый | неопределенность | сложность | сложность |
| Однопользованная биг-труба | 1 | Маленький | хороший | медленный | Настраивать | в целом | в целом |
| Многопользовательская бирга | 1 | Общий (вызванный пулом резьбов) | хороший | Самый быстрый | неопределенность | Самый сложный | в целом |
| свойство | тип | Это требуется | Значение по умолчанию | иллюстрировать | описывать |
|---|---|---|---|---|---|
| размер ядра | инт | нет | -1 | Количество основных потоков | Минимальное количество простоя, минимальное количество потоков, которое в любом случае выживет |
| максимальный размер | инт | нет | 1024 | Максимальное количество потоков | Jpipe может создать максимальное количество потоков, используемых для обработки Pagelets |
| размер очереди | инт | нет | 1024 | Максимальное количество со-колокол | Запрос параллелизма больше, чем максимальный размер, и он будет помещен в очередь и ждал. |
| Сохранить | длинный | нет | 60000 | Максимальное время простоя (мс) | Если количество потоков превышает размер ядра, оно будет переработано до тех пор, пока количество потоков не будет равным размеру ядра. |
| предварительно отпуск на все ядро | логический | нет | ЛОЖЬ | Разогрейте бассейн | Стоит ли предварительно запустить потоки размером с ядра |
| свойство | тип | Это требуется | Значение по умолчанию | иллюстрировать | описывать |
|---|---|---|---|---|---|
| асинхро | логический | нет | истинный | Сделать ли задачи с асинхронно |
| свойство | тип | Это требуется | Значение по умолчанию | иллюстрировать | описывать |
|---|---|---|---|---|---|
| домид | нить | да | HTML -идентификатор документа | ||
| фасоль | нить | да | Имя весеннего боба | ||
| вар | нить | да | переменные параметры | ||
| Ури | нить | нет | параметры URI | ||
| jsmethod | нить | нет | JP.View | Функция JS, которая завершает данные |
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 ();
}через стартовый стартер
< 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 Используйте Spring's @Service , чтобы определить паджет для реализации метода 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 и причал
@ 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, необходимо ввести контейнеры сервлетов, которые поддерживают JSP 1.1 или JSP 1.2 (развертывание контейнеров сервлетов, такие как Tomcat и Jetty), и FTL можно использовать в не-сервис-средах и других веб-средах.
Более точное объяснение: хотя контейнер сервлета не имеет локальной поддержки JSP, вы также можете использовать библиотеку тегов JSP в Freemarker. Просто убедитесь, что пакет javax.servlet.jsp.* Для JSP версии 1.2 (или более новой) доступен в веб -приложении. Если ваш сервенчный контейнер поддерживает только JSP 1.1, то вам нужно скопировать следующие шесть классов (например, вы можете извлечь из пакета JAR Tomcat 5.x или Tomcat 4.x) в каталог веб-приложения: javax.servlet.jsp.itext.iter javax.servlet.servletcontextlistener, javax.servlet.servletContextattributeListener, javax.servlet.http.httpsessionattributeListener, javax.servlet.http.httpsessionListener. Тем не менее, имейте в виду, что, поскольку контейнер поддерживает только JSP 1.1, обычно используя более ранние версии перед сервлетом 2.3, слушатели событий не могут быть поддержаны, поэтому библиотека тегов JSP 1.2 для регистрации слушателей событий будет работать нормально.
На момент прессы: 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 >Поскольку контейнеры, такие как щипцов, не имеют среды JSP-API, им необходимо полагаться на пакет javax.servlet.jsp-api, и в то же время им необходимо настроить класс-точки Freemarker через Taglibfactory. Без этой конфигурации сообщается об ошибке: freemarker.ext.jsp.taglibfactory $ taglibgettingexception: не было найдено для "http://java.ylline.top/jsp/jpipe" jsp taglib uri. (TLD-S проводятся в соответствии с спецификацией JSP 2.2. В настройках разработки и встроенных спертлетов вам также может понадобиться «metainftldsources» и «classpathtlds» freemarker.ext.servlet.freemarkerservlet init-params или аналогичные свойства системы.).
Конфигурация
@ 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 部署 -->Поскольку в Tomcat и Srilty уже есть среда JSP-API, на пакет javax.servlet.jsp-api здесь нет необходимости больше