Я использую Camel 2.18 и Java 8. Ниже приведен код с маршрутизацией.Я помещаю такой JSON в этот сервис:
{
"bigField": "testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest",
"smallField": "234"
}
И проблема в том, что bigField довольно большой, может быть 256MB.Вот почему я думаю о потоковом кешировании в Camel: http://camel.apache.org/stream-caching.html Не уверен, смогу ли я применить его в моем сценарии?Что я понимаю, что этот механизм должен хранить поток на диске понемногу?Я создал / tmp / cachedir и вижу, как Camel создает и удаляет некоторые временные файлы.
6:15:23.505 [qtp422330142-21 - /myservice/v1/oper] DEBUG org.apache.camel.util.FileUtil - Retrying attempt 0 to delete file: /tmp/cachedir/cos7138988885969104934.tmp
16:15:23.505 [qtp422330142-21 - /myservice/v1/oper] DEBUG org.apache.camel.util.FileUtil - Tried 1 to delete file: /tmp/cachedir/cos7138988885969104934.tmp with result: true
16:15:23.505 [qtp422330142-21 - /myservice/v1/oper] DEBUG org.apache.camel.util.FileUtil - Retrying attempt 0 to delete file: /tmp/cachedir/cos8802932624903146810.tmp
16:15:23.505 [qtp422330142-21 - /myservice/v1/oper] DEBUG org.apache.camel.util.FileUtil - Tried 1 to delete file: /tmp/cachedir/cos8802932624903146810.tmp with result: true
16:15:23.505 [qtp422330142-21 - /myservice/v1/oper] DEBUG org.apache.camel.util.FileUtil - Retrying attempt 0 to delete file: /tmp/cachedir/cos91165405800652292.tmp
16:15:23.505 [qtp422330142-21 - /myservice/v1/oper] DEBUG org.apache.camel.util.FileUtil - Tried 1 to delete file: /tmp/cachedir/cos91165405800652292.tmp with result: true
16:15:23.506 [qtp422330142-21 - /myservice/v1/oper] DEBUG org.apache.camel.util.FileUtil - Retrying attempt 0 to delete file: /tmp/cachedir/cos6540772182497948066.tmp
16:15:23.506 [qtp422330142-21 - /myservice/v1/oper] DEBUG org.apache.camel.util.FileUtil - Tried 1 to delete file: /tmp/cachedir/cos6540772182497948066.tmp with result: true
16:15:23.506 [qtp422330142-21 - /myservice/v1/oper] DEBUG org.eclipse.jetty.server.Server - RESPONSE /myservice/v1/oper 201
Так что, похоже, работает.Но я использую этот механизм, чтобы защитить себя от исключений OutOfMemory.Итак, я написал Junit, отправляя bigField, созданный так:
headers.setAll(map);
char[] chars = new char[20000000];
Arrays.fill(chars, 'a');
String bigField = new String(chars);
Я запустил свое приложение Spring Boot с JAVA_OPTS="-Xms60m -Xmx128m"
Чего мне не хватает?Я думал, что этот механизм потокового кэширования защитит меня от клиентов, отправляющих события размером более Xmx - 128 МБ, но он не работает на 20 МБ.
@SpringBootApplication
public class Application extends RouteBuilder {
@Override
public void configure() throws Exception {
setupStreamCaching();
restConfiguration().host("0.0.0.0").port(PORT)
.endpointProperty("headerFilterStrategy", "#myHeaderFilterStrategy")
.endpointProperty("matchOnUriPrefix", "true")
.endpointProperty("sendServerVersion", "false")
.bindingMode(RestBindingMode.json);
rest(API_CONTEXT + V1)
.post(API_OPERATION)
.type(RequestModel.class)
.outType(Response.class)
.consumes(APPLICATION_JSON)
.produces(APPLICATION_JSON)
.to(MAIN_ROUTE);
from(MAIN_ROUTE)
.routeId(MAIN_ROUTE)
.process(requestValidator)
.to(SERVICE_CALL)
.end();
private void setupStreamCaching() {
getContext().getStreamCachingStrategy().setSpoolDirectory("/tmp/cachedir");
getContext().getStreamCachingStrategy().setSpoolThreshold(64 * 1024);
getContext().getStreamCachingStrategy().setBufferSize(16 * 1024);
}
http://camel.apache.org/stream-caching.html
3: 30: 24.584 [qtp1492219097-24 - / myservice / v1 / oper] DEBUG org.eclipse.jetty.io.ChannelEndPoint - заполнено 3432 SelectChannelEndPoint @ 44b2fa12 {/10.0.2.2:57125 <-> 1080, открыть, войти, выйти, -,-, 0/30000, HttpConnection} {io = 0, kio = 0, kro = 1} 13: 30: 24.585 [qtp1492219097-24 - / myservice / v1 / oper] DEBUG oejetty.server.HttpConnection - HttpConnection @ 13dbbbcc [REFILLING, SelectChannelEndPoint @ 44b2fa12 {/10.0.2.2:57125 <-> 1080, Open, в, из, -, -, 0/30000, HttpConnection} {Io = 0, КИО = 0, кро = 1}] [р = HttpParser{s = CONTENT, 19996672 из 20000104}, g = HttpGenerator {s = START}, c = HttpChannelOverHttp @ 4b6953ae {r = 1, c = false, a = DISPATCHED, uri = / myservice / v1 / oper}] заполнено 3432 13: 30: 24.585 [qtp1492219097-24 - / myservice / v1 / oper] DEBUG org.eclipse.jetty.http.HttpParser - parseNext s = CONTENT HeapByteBuffer @ 42f6e192 [p = 0, l = 3432, c = 8322, c = 8192,] = {<< >> aaaaaaaaaaaaaaaaa ...aaaaaaaaaaaaaa} 13: 30: 24.585 [qtp1492219097-24 - / myservice / v1 / oper] DEBUG org.eclipse.jetty.server.HttpChannel - HttpChannelOverHttp @ 4b6953ae {r = 1, u = user, c = false, cser = false/ v1 / oper} content java.nio.HeapByteBufferR [pos = 0 lim = 3432 cap = 8192] 13: 30: 24.585 [qtp1492219097-24 - / myservice / v1 / oper] DEBUG org.eclipse.jetty.http.HttpParser -parseNext s = СОДЕРЖАНИЕ HeapByteBuffer @ 42f6e192 [p = 3432, l = 3432, c = 8192, r = 0] = {aaaaaaaaaaaaaaaaaaa ...- 21T17: 32: 28Z "} <<< >>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa что что-что также, тоже.13: 30: 24.585 [qtp1492219097-24 - / myservice / v1 / oper] DEBUG org.eclipse.jetty.http.HttpParser - CONTENT -> КОНЕЦ 13: 30: 24.585 [qtp1492219097-24 - / myservice / v1 / oper]DEBUG org.eclipse.jetty.server.HttpChannel - HttpChannelOverHttp @ 4b6953ae {r = 1, c = false, a = DISPATCHED, uri = / myservice / v1 / oper} messageComplete 13: 30: 24.585 [qtp149221ser-24]v1 / oper] DEBUG org.eclipse.jetty.server.HttpInput - HttpInputOverHTTP @ 63602aee EOF 13: 30: 24.585 [qtp1492219097-24 - / myservice / v1 / oper] DEBUG org.eclipse.jetty.io.ChannelEndPoint - заполнено 0 SelectChannelEndPoint @ 44b2fa12 {/10.0.2.2:57125 <-> 1080, Открыть, войти, выйти, -, -, 1/30000, HttpConnection} {io = 0, kio = 0, kro = 1} 13: 30: 24.586 [qtp1492219097-24 - / myservice / v1 / oper] DEBUG oejetty.server.HttpConnection - HttpConnection @ 13dbbbcc [REFILLING, SelectChannelEndPoint @ 44b2fa12 {/10.0.2.2:57125 <-> 1080, в, 1080,out, -, -, 2/30000, HttpConnection} {io = 0, kio = 0, kro = 1}] [p = HttpParser {s = END, 20000104 из 20000104}, g = HttpGenerator {s = START}, c= HttpChannelOverHttp @ 4b6953ae {r = 1, c = false, a = ОТПРАВЛЕНО, uri = / myservice / v1 / oper}] заполнено 0 13: 30: 24.586 [qtp1492219097-24 - / myservice / v1 / oper] DEBUG org.eclipse.jetty.[qtp1492219097-24 - / myservice / v1 / oper] WARN oejetty.servlet.ServletHandler - / myservice / v1 / oper org.apache.camel.TypeConversionException: ошибка при преобразовании типа из типа: java.lang.String в требуемый тип: java.lang.String со значением [Body является экземпляром org.apache.camel.StreamCache] из-заjava.lang.OutOfMemoryError: Пространство кучи Java
java.lang.OutOfMemoryError: Пространство кучи Java в org.apache.camel.impl.converter.BaseTypeConverterRegistry.createTypeConversionException (BaseTache.java) atg.camel.impl.converter.BaseTypeConverterRegistry.convertTo (BaseTypeConverterRegistry.java:150) в org.apache.camel.impl.MessageSupport.getBody (MessageSupport.java:78) в org.apache.camel.implSort.Message.Supp.java: 53) в org.apache.camel.util.MessageHelper.extractBodyAsString (MessageHelper.java:84) в org.apache.camel.component.rest.RestConsumerBindingProcessor.process (RestConsumerBindingProcessor.java:16apl) на org..management.InstrumentationProcessor.process (InstrumentationProcessor.java:77) в org.apache.camel.processor.RedeliveryErrorHandler.process (RedeliveryErrorHandler.java:542) в org.apache.camel.processor.CamelInternalProoror.In) в org.apache.camel.processor.Pipeline.process (Pipeline.java:120) в org.apache.camel.processor.Pipeline.process (Pipeline.java:83) в org.apache.camel.processor.CamelInternalProcessor.process (CamelInternalProcessor.java:197) в org.apache.camel.component.jetty.CamelContinuationServlet.doService (CamelContinuationServlet.java:191) в org.apache.camel.http.common.CamelServlet.service (CamelServlet.java:74) в javax.servlet.pserv.serp.pv.java: 790) в org.eclipse.jetty.servlet.ServletHolder.handle (ServletHolder.java:812) в org.eclipse.jetty.servlet.ServletHandler.doHandle (ServletHandler.java:587) в org.etlip.server.handler.ContextHandler.doHandle (ContextHandler.java:1127) в org.eclipse.jetty.servlet.ServletHandler.doScope (ServletHandler.java:515) в org.eclipse.jetty.server.handler.ContextHandler.dolerJava: 1061) в org.eclipse.jetty.server.handler.ScopedHandler.handle (ScopedHandler.java:141) в org.eclipse.jetty.server.handler.HandlerWrapper.handle (HandlerWrapper.java:97) в org.eclipse.jetty.server.Server.handle (Server.java:499) в org.eclipse.jetty.server.HttpChannel.handle (HttpChannel.java:311) в org.eclipse.jetty.server.HttpConnection.onFillable (HttpConnection.Java: 257) в org.eclipse.jetty.io.AbstractConnection $ 2.run (AbstractConnection.java:544) в org.eclipse.jetty.util.thread.QueuedThreadPool.runJob (QueuedThreadPool.java:635l) в org.jetty.util.thread.QueuedThreadPool $ 3.run (QueuedThreadPool.java:555) в java.lang.Thread.run (Thread.java:748) Причина: org.apache.camel.RuntimeCamel Исключение: java.lang.OutOfMemEEпространство кучи в org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException (ObjectHelper.java:1763) в org.apache.camel.util.ObjectHelper.invokeMethod (ObjectHelper.java:1358) в org.apache.camel.StaticMethodTypeConverter.convertTo (StaticMethodTypeConverter.java:59) в org.apache.camel.impl.converter.BaseTypeConverterRegistry.doConvertTo (BaseTypeConverterRegistry.java:306) в org.apimpc.onverterRegistry.convertTo (BaseTypeConverterRegistry.java:133) ... пропущено 27 общих фреймов
Причина: java.lang.OutOfMemoryError: Пространство кучи Java в java.util.Arrays.copyOf (Arrays.java:3332)в java.lang.AbstractStringBuilder.ensureCapacityInternal (AbstractStringBuilder.java:124) в java.lang.AbstractStringBuilder.append (AbstractStringBuilder.java:596) в java.lang.StringBuilder.append (StringBaglider.apj.jpg).camel.converter.IOConverter.toString (IOConverter.java:318) в org.apache.camel.converter.IOConverter.toString (IOConverter.java:307) в org.apache.camel.converter.IOConverter.toString (IOConverter.j364) в sun.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод) вsun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) в java.lang.redj.injg.tg.camel.util.ObjectHelper.invokeMethod (ObjectHelper.java:1354) на org.apache.camel.impl.converter.StaticMethodTypeConverter.convertTo (StaticMethodTypeConverter.java:59) в org.(BaseTypeConverterRegistry.java:306) в org.apache.camel.impl.converter.BaseTypeConverterRegistry.convertTo (BaseTypeConverterRegistry.java:133) в org.apache.camel.impl.MessageSupport.get78 или at.apache.camel.impl.MessageSupport.getBody (MessageSupport.java:53) в org.apache.camel.util.MessageHelper.extractBodyAsString (MessageHelper.java:84) в org.apache.camel.component.rest.RestConsuProB (RestConsumerBindingProcessor.java:162) в org.apache.camel.management.InstrumentationProcessor.process (InstrumentationProcessor.java:77) в org.apache.camel.processor.RedeliveryErrorHandler.process (RedeliveryErrorHandler.java:542) в org.apache.camel.processor.CamelInternalProcessor.process (CamelInternal):.apache.camel.processor.Pipeline.process (Pipeline.java:120) в org.apache.camel.processor.Pipeline.process (Pipeline.java:83) в org.apache.camel.processor.CamelInternalProcessor.process (CamelInternalProcessor.java: 197) в org.apache.camel.component.jetty.CamelContinuationServlet.doService (CamelContinuationServlet.java:191) в org.apache.camel.http.common.CamelServlet.service (CamelServlet.java: 74).servlet.http.HttpServlet.service (HttpServlet.java:790) в org.eclipse.jetty.servlet.ServletHolder.handle (ServletHolder.java:812) в org.eclipse.jetty.servlet.ServletHandler.java587) в org.eclipse.jetty.server.handler.ContextHandler.doHandle (ContextHandler.java:1127)