Распределенная система журналов: развертывание Plumelog и доступ к системе
Распределенная система журналов: развертывание Plumelog и доступ к системе

Экологическая подготовка

  • Пожалуйста, терпеливо прочтите документ и следуйте инструкциям перед его использованием. Вам необходимо иметь определенное представление об основах двух основных платформ: logback и log4j.

На что следует обратить внимание #

  • Plumelog имеет три режима запуска:,Redis, Kafka, Lite соответственно,Плюс встроенная версия Pumelog-lite,Каждый использует развертывание по своим потребностям.
  • Облегченный режим — это автономная версия.,Начните использовать напрямую, не полагаясь на какое-либо внешнее промежуточное программное обеспечение.,развернуть Очень удобно,Но производительность ограничена,Может обрабатывать в пределах 10G в день,Предпочтительно SSD жесткий диск,Подходит для молодых игроков в категории «Система управления».,В компании много небольших компаний, которым необходимо централизованное управление.
  • redis,kafkaШаблоны можно группироватьраспределенныйразвертывать,Подходит для крупных игроков.,Интернет-компания,В частности, использовать ли Redis или Kafka?,Посмотрите на статус эксплуатации и технического обслуживания каждой компании.
  • Plumelog-lite Встроенная интегрированная версия Pumelog, на которую напрямую ссылается pom, встроенная в проект, с собственным интерфейсом запросов, подходящая для одного независимого небольшого проекта, лучший компаньон для аутсорсингового программного обеспечения.

1. Установка и настройка сервера #

(1) Установка сервера #

Шаг 1: Установка redis или kafka (redis достаточно для обычных компаний) redis Официальный сайт:https://redis.io kafka:http://kafka.apache.org

Шаг 2. Установите адрес загрузки официального сайта elasticsearch: https://www.elastic.co/cn/downloads/past-releases.

Шаг 3. Загрузите установочный пакет, адрес загрузки plamelog-server: https://gitee.com/plumeorg/plumelog/releases.

Шаг 4. Настройте Pumelog-сервер и запустите его. В Redis и Kafka можно развернуть несколько серверов Pumelog в режиме очереди для достижения высокой доступности. Конфигурация одинакова.

Шаг 5:Подробную информацию о синтаксисе фонового запроса см.руководство по использованию шлейфа

(2) Конфигурация сервера #
  • Подробное объяснение файла Plumelog-server/application.properties:
Язык кода:javascript
копировать
#Значение — 4 типа redis,kafka,rest,restServer,lite
#redis Указывает использование Redis в качестве очереди
#kafka Указывает на использование Kafka в качестве очереди.
#rest Указывает на бревно взятие из остального интерфейса.
#restServer Указывает на запуск в качестве сервера интерфейса отдыха.
#ui Указывает на запуск в одиночку как ui
#lite Запуск в простом режиме не требует конфигурацииredis, es и т.п.
plumelog.model=redis
#Путь хранения бревно в облегченном режиме
#plumelog.lite.log.path=/lucene

#Если вы используете Kafka, включите следующую конфигурацию
#plumelog.kafka.kafkaHosts=172.16.247.143:9092,172.16.247.60:9092,172.16.247.64:9092
#plumelog.kafka.kafkaGroupName=logConsumer

#Адрес Redis очереди, модель Конфигурация Режим кластера Redis, режим Sentinel, разделенные запятыми, Redis очереди не поддерживает режим кластера, облегченный режим можно закомментировать Конфигурация
#Когда производительности очереди Redis недостаточно, вы можете создать отдельную очередь Redis для разных проектов, использовать отдельный Pumelog-сервер для сбора и использовать общий Redis управления
plumelog.queue.redis.redisHost=127.0.0.1:6379
#Если у вас есть пароль при использовании Redis, включите следующую Конфигурацию
#plumelog.queue.redis.redisPassWord=123456
#Если вы хотите переключить базу данных, Redis должен потребовать пароль конфигурации.
#plumelog.queue.redis.redisDb=0
#Режим Sentinel требует Конфигурации
#plumelog.queue.redis.sentinel.masterName=myMaster
Режим декомпрессии #redis, не использует несжатые очереди после включения
#plumelog.redis.compressor=true

#Адрес Redis управления , кластеры разделяются запятыми, а не Конфигурация будет доступна в очереди, в облегченном режиме можно закомментировать все последующие Конфигурация, управление Redis поддерживает режим кластера при использовании отдельно
#plumelog.redis.redisHost=127.0.0.1:6379
#Если у вас есть пароль при использовании Redis, включите следующую Конфигурацию
#plumelog.redis.redisPassWord=123456
#plumelog.redis.redisDb=0
#Режим Sentinel требует Конфигурации
#plumelog.redis.sentinel.masterName=myMaster

#Если вы используете отдых, включите следующую конфигурацию
#plumelog.rest.restUrl=http://127.0.0.1:8891/getlog
#plumelog.rest.restUserName=plumelog
#plumelog.rest.restPassWord=123456

#elasticsearch linked Конфигурация. Хосты поддерживают протоколы передачи данных, такие как: http, https, кластеры, разделенные запятыми, в облегченном режиме можно закомментировать следующую конфигурацию.
plumelog.es.esHosts=127.0.0.1:9200
plumelog.es.shards=5
plumelog.es.replicas=1
plumelog.es.refresh.interval=30s
#бревно Метод создания индекса день означает по дням, час означает по часам
plumelog.es.indexType.model=day
Конфигурация обязательна в режиме #hour
#plumelog.es.maxShards=100000
#ES Установить пароль, включить следующую конфигурацию
#plumelog.es.userName=elastic
#plumelog.es.passWord=elastic
#Доверять ли самоподписанным сертификатам
#plumelog.es.trustSelfSigned=true
#Проверка имени хоста
#plumelog.es.hostnameVerification=false

#Следующая конфигурация должна быть Конфигурация независимо от режима
#Одиночный номер бревно
plumelog.maxSendSize=100
#Вытягивание временного интервала, Кафка не вступает в силу
plumelog.interval=100
Адрес #plumelog-ui Если это не Конфигурация, вы не сможете перейти по ссылке в тревожном сообщении.
plumelog.ui.url=http://demo.plumelog.com


#Manage пароль, пароль, который необходимо вводить при бревно ручном удалении
admin.password=123456
#бревноRetention дней,Конфигурация0или нет Конфигурацияпостоянное хранение по умолчанию
admin.log.keepDays=30
#Дни хранения ссылок, Конфигурация0или нет. По умолчанию в конфигурации установлено постоянное хранение.
admin.log.trace.keepDays=30
#Login Конфигурация, после Конфигурации будет интерфейс входа в систему
#login.username=admin
#login.password=admin
(3) Запустите PlumeServer.

windows : startup.bat Уведомление:Запустите cmd или powershell в режиме администратора.

linux: stratup.sh

2. Использование клиента #

(1)На что следует обратить внимание #
(2) Конфигурация клиента #
1.log4j #
  • представлять
Язык кода:javascript
копировать
<dependency>
    <groupId>com.plumelog</groupId>
    <artifactId>plumelog-log4j</artifactId>
    <version>3.5.2</version>
</dependency>
  • Конфигурацияlog4jКонфигурациядокумента добавьте следующий Appender, пример следующий:
Язык кода:javascript
копировать
#Выберите один из трех, чтобы присоединиться к root
log4j.rootLogger=INFO,stdout,L
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} [%c.%t]%n%m%n
#kafka как промежуточное ПО
log4j.appender.L=com.plumelog.log4j.appender.KafkaAppender
Имя #appNameсистема (определите сами)
log4j.appender.L.appName=plumelog
log4j.appender.L.env=${spring.profiles.active}
log4j.appender.L.kafkaHosts=172.16.247.143:9092,172.16.247.60:9092,172.16.247.64:9092
#redis как промежуточное ПО
log4j.appender.L=com.plumelog.log4j.appender.RedisAppender
log4j.appender.L.appName=plumelog
log4j.appender.L.env=${spring.profiles.active}
log4j.appender.L.redisHost=172.16.249.72:6379
#redis Нет пароля, этот элемент пуст или не требуется
#log4j.appender.L.redisAuth=123456
#облегченный режим
log4j.appender.L=com.plumelog.log4j.appender.LiteAppender
log4j.appender.L.appName=plumelog
log4j.appender.L.env=${spring.profiles.active}
log4j.appender.L.plumelogHost=localhost:8891

Точно так же, если вы используете logback, настройте его с помощью log4j2 следующим образом, и пример выглядит следующим образом:

2.logback #
  • представлять
Язык кода:javascript
копировать
<dependency>
    <groupId>com.plumelog</groupId>
    <artifactId>plumelog-logback</artifactId>
    <version>3.5.2</version>
</dependency>
  • Конфигурация
Язык кода:javascript
копировать
<appenders>
    <!--использоватьredisВключить ниже Конфигурация-->
    <appender name="plumelog" class="com.plumelog.logback.appender.RedisAppender">
        <appName>plumelog</appName>
        <redisHost>172.16.249.72:6379</redisHost>
        <redisAuth>123456</redisAuth>
    </appender>
    <!-- Используйте Kafka, чтобы включить следующую конфигурацию -->
    <appender name="plumelog" class="com.plumelog.logback.appender.KafkaAppender">
        <appName>plumelog</appName>
        <kafkaHosts>172.16.247.143:9092,172.16.247.60:9092,172.16.247.64:9092</kafkaHosts>
    </appender>
    <!-- Используйте упрощенный режим, чтобы включить следующую конфигурацию. -->
    <appender name="plumelog" class="com.plumelog.logback.appender.LiteAppender">
        <appName>worker</appName>
        <plumelogHost>localhost:8891</plumelogHost>
    </appender>
</appenders>
        <!--использовать上面三个三选一加入到rootпод-->
<root level="INFO">
<appender-ref ref="plumelog"/>
</root>
3. Рекомендуется использовать интегрированный центр конфигурации Logback, скопируйте все, если вы не знаете, как его настроить. #
  • Добавьте в application.properties
Язык кода:javascript
копировать
plumelog.appName=plumelog_demo
plumelog.redisHost=127.0.0.1:6379
plumelog.redisAuth=plumelogredis
spring.profiles.active=dev
  • logback-spring.xml Не знаю как скопировать всю Конфигурацию
Язык кода:javascript
копировать
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
    <conversionRule conversionWord="wex"
                    converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
    <conversionRule conversionWord="wEx"
                    converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
    <!-- Цвет бревно формат -->
    <property name="CONSOLE_LOG_PATTERN"
              value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
    <!--вывод на консоль-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--фильтрtraceбревноутешать-->
        <filter class="com.plumelog.logback.util.FilterSyncLogger">
            <level></level>
        </filter>
        <encoder>
            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
            <!-- Установить набор символов -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
  <!-- Вывод в документ -->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <FileNamePattern>logs/plumelog-demo.log.%d{yyyy-MM-dd}.log</FileNamePattern>
        <MaxHistory>3</MaxHistory>
      </rollingPolicy>
      <encoder>
        <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
        <!-- Установить набор символов -->
        <charset>UTF-8</charset>
      </encoder>
    </appender>
  <!-- среда Конфигурация -->
    <springProperty scope="context" name="plumelog.appName" source="plumelog.appName"/>
    <springProperty scope="context" name="plumelog.redisHost" source="plumelog.redisHost"/>
    <springProperty scope="context" name="plumelog.redisPort" source="plumelog.redisPort"/>
    <springProperty scope="context" name="plumelog.redisAuth" source="plumelog.redisAuth"/>
    <springProperty scope="context" name="plumelog.redisDb" source="plumelog.redisDb"/>
    <springProperty scope="context" name="plumelog.env" source="spring.profiles.active"/>
   <!-- выходной шлейф -->
    <appender name="plumelog" class="com.plumelog.logback.appender.RedisAppender">
        <appName>${plumelog.appName}</appName>
        <redisHost>${plumelog.redisHost}</redisHost>
        <redisAuth>${plumelog.redisAuth}</redisAuth>
        <redisDb>${plumelog.redisDb}</redisDb>
        <env>${plumelog.env}</env>
    </appender>
    <!-- Конфигурациябревновыход,Выводить только информацию,Оставьте только консоль иplumelogвыход-->
  <!-- 正常开发среда本地,Выводить только на консоль,测试среда只выход到plumelog,Производственная среда выводит данные в локальный документplumelog.,потому что естьplumelogБлагослови местныхдокумент Просто держи это3Всего несколько дней-->
  <!-- 这些都可以根据среда Конфигурация Разная загрузкаref->
    <root level="info">
      <!--вывод на консоль-->
        <appender-ref ref="CONSOLE"/>
      <!-- Вывод в документ -->
        <appender-ref ref="file"/>
      <!-- выходной шлейф -->
        <appender-ref ref="plumelog"/>
    </root>
  
</configuration>
  • Совмещено со средой Конфигурация корпуса
Язык кода:javascript
копировать
    <springProfile name="dev">
        <root level="INFO">
            <appender-ref ref="CONSOLE" />
        </root>
    </springProfile>
    <springProfile name="test">
        <root level="INFO">
            <appender-ref ref="FILE" />
        </root>
    </springProfile>
    <springProfile name="prod">
    <root level="INFO">
      <appender-ref ref="FILE" />
    </root>
    </springProfile>
  • Совет: почему весна Boot рекомендует использовать logback-spring.xml вместо logback.xml для анализа проблем с конфигурацией logback. То есть logback.xml загружается раньше, чем application.properties, поэтому, если вы используете переменную в logback.xml, и эта переменная окажется записанной в application.properties, вы не сможете ее просто изменить на. logback-spring. xml может решить эту проблему. Вот почему некоторые люди не могут загрузить удаленную конфигурацию при использовании nacos и других центров конфигурации. Это из-за проблемы с приоритетом загрузки.
4.log4j2 #
  • представлять
Язык кода:javascript
копировать
<dependency>
    <groupId>com.plumelog</groupId>
    <artifactId>plumelog-log4j2</artifactId>
    <version>3.5.2</version>
</dependency>       
  • Конфигурация,Примеры следующие:
Язык кода:javascript
копировать
<appenders>
    <!-- Используйте Kafka, чтобы включить следующую конфигурацию -->
    <KafkaAppender name="kafkaAppender" appName="plumelog"
                   kafkaHosts="172.16.247.143:9092,172.16.247.60:9092,172.16.247.64:9092">
    </KafkaAppender>

    <!--использоватьredisВключить ниже Конфигурация-->
    <RedisAppender name="redisAppender" appName="plumelog" redisHost="172.16.249.72:6379" redisAuth="123456">
    </RedisAppender>

    <!--использоватьliteВключить ниже Конфигурация-->
    <LiteAppender name="liteAppender" appName="plumelog" plumelogHost="localhost:8891">
    </LiteAppender>
</appenders>

<loggers>
<root level="INFO">
  <!--использовать上面三个三选一加入到rootпод-->
    <appender-ref ref="redisAppender"/>
</root>
</loggers>

3. Скриншоты системы

4. Сборник часто задаваемых вопросов

  • Какую роль Redis играет в проекте? Redis выполняет в проекте две роли: первая — действовать как очередь сообщений в режиме Redis, а вторая — хранить метаданные и управлять сигналами самого проекта.
  • Почему я не могу найти данные в Redis, но не могу найти их в фоновом режиме? Такая ситуация скорее всего на сервере plumelog.queue.redis.redisHost Нет. Конфигурация правильная. Redis действует только как очередь. Если вы видите в нем данные, это означает, что сервер отсутствует и потребление отсутствует. Обычно Redis не задерживается.
  • Почему я не могу найти бревно в админке после регистрации Конфигурации? Метод устранения неисправности: Первый шаг: Остановите сервер, запустите проект сбора бревно и посмотрите, есть ли данные в Redis. Если есть объяснение, можно войти в очередь из проекта. Если нет, проверьте, есть ли данные в Redis. на стороне проекта правильно; Шаг 2. Если в Redis Data есть данные, запустите сервер, если на сервере есть ElasticSearch. commit! успех указывает на успех ссылки; Многие друзья, Конфигурация, установили клиент, но logback.xmlилиlog4j2.xml вообще не вступает в силу, поэтому в это время вам нужно остановить Plumelog-server, сделать первый шаг к Redis, и после того, как Redis будет набран, запустите Pumelog-Server и увидите, что бревно Потребление указывает на успех.
  • Почему я не вижу данных при отслеживании ссылок? Модуль отслеживания ссылок, созданный модулем отслеживания ссылок, относительно большой.,Учитывая игроков с низким спросом,Не интегрировано по умолчанию,Требуется отдельно Конфигурация,Посмотреть документацию подробно:Настройка отслеживания ссылок Если после Конфигурации данных о ссылке по-прежнему нет, во-первых, проверьте, есть ли TraceID, а во-вторых, эффективен ли ваш АОП?
  • Можно ли использовать клиент Pumelog Конфигурация вместе с центром Конфигурация документов? Это определенно возможно, шлейф Конфигурация - это Конфигурация в трех основных бревно-фреймворках Конфигурация В документе вы можете использовать SpringProperty для управления Конфигурацией. Конкретная операция зависит от ситуации каждого проекта.
  • Каков известный размер нынешней производственной среды Pumelog? Согласно отзывам пользователей, наибольший ежедневный объем собранных пользователей достиг 3 ТБ и работает стабильно.
  • Почему мой проект сообщает об ошибке при запуске после наследования шлейфа? Если появляется сообщение о том, что соединение Redis не удалось, это означает, что конфигурация redis неверна. Если это другая ошибка, например, если не удается найти класс запроса, это должно быть связано с тем, что данные бревноконфигурации неверны. Сначала освойте значение тегов в файле log4j и документе конфигурации журнала.
  • Повлияет ли шлейф на исходную бревноконфигурацию? Нет, шлейф только добавляет выходные данные и не влияет на исходную конфигурацию.
  • Повлияет ли шлейф на эффективность проекта? Почти нет, Pumelog-lite может сделать это при запросе, его необходимо внедрить
  • Нет данных при раскрытии раскрывающегося списка имени приложения? Что происходит? Чтобы обеспечить производительность, расширение раскрывающегося списка будет загружаться только при первой загрузке. Если в тот же день есть бревно, но при его раскрытии нет значения, это может быть ошибкой во время. создание индекса. Как это проверить? Войдите на страницу управления, нажмите на стрелку напротив бревно дня в таблице текущих данных, чтобы развернуть ее. Если в ней есть данные, это означает, что с индексом все в порядке. В это время просто закройте браузер и повторите попытку. входить. Если после расширения ничего не найдено, это означает, что информация о группировке была потеряна при создании индекса. Выберите ее и нажмите «Сбросить индекс», закройте браузер и повторите вход.
  • Почему я не могу загрузить параметры при использовании единого центра конфигурации nacos? Spring Boot рекомендует использовать logback-spring.xml вместо logback.xml для анализа проблем с конфигурацией logback. То есть logback.xml загружается раньше, чем application.properties, поэтому, если вы используете переменную в logback.xml, и эта переменная окажется записанной в application.properties, вы не сможете ее просто изменить на. logback-spring. xml может решить эту проблему. Вот почему некоторые люди не могут загрузить удаленную конфигурацию при использовании nacos и других центров конфигурации. Это из-за проблемы с приоритетом загрузки.
  • Что делать, если шлейф завис и потерялся? Проектное расположение бревно-запроса - система бревно. Невозможно жертвовать производительностью ради высокой идемпотентности или даже влиять на клиента. Поэтому, если вы обеспокоены тем, что бревно зависает и не можете найти бревно, вы можете просмотреть Конфигурацию локально. .бревно держать три дня в качестве добавки.

другой

Ссылка: http://www.plumelog.com/zh-cn/docs/FASTSTART.html.

https://my.oschina.net/u/3245438/blog/5562226

boy illustration
Углубленный анализ переполнения памяти CUDA: OutOfMemoryError: CUDA не хватает памяти. Попыталась выделить 3,21 Ги Б (GPU 0; всего 8,00 Ги Б).
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Прочитайте нейросетевую модель Трансформера в одной статье
boy illustration
.ART Теплые зимние предложения уже открыты
boy illustration
Сравнительная таблица описания кодов ошибок Amap
boy illustration
Уведомление о последних правилах Points Mall в декабре 2022 года.
boy illustration
Даже новички могут быстро приступить к работе с легким сервером приложений.
boy illustration
Взгляд на RSAC 2024|Защита конфиденциальности в эпоху больших моделей
boy illustration
Вы используете ИИ каждый день и до сих пор не знаете, как ИИ дает обратную связь? Одна статья для понимания реализации в коде Python общих функций потерь генеративных моделей + анализ принципов расчета.
boy illustration
Используйте (внутренний) почтовый ящик для образовательных учреждений, чтобы использовать Microsoft Family Bucket (1T дискового пространства на одном диске и версию Office 365 для образовательных учреждений)
boy illustration
Руководство по началу работы с оперативным проектом (7) Практическое сочетание оперативного письма — оперативного письма на основе интеллектуальной системы вопросов и ответов службы поддержки клиентов
boy illustration
[docker] Версия сервера «Чтение 3» — создайте свою собственную программу чтения веб-текста
boy illustration
Обзор Cloud-init и этапы создания в рамках PVE
boy illustration
Корпоративные пользователи используют пакет регистрационных ресурсов для регистрации ICP для веб-сайта и активации оплаты WeChat H5 (с кодом платежного узла версии API V3)
boy illustration
Подробное объяснение таких показателей производительности с высоким уровнем параллелизма, как QPS, TPS, RT и пропускная способность.
boy illustration
Удачи в конкурсе Python Essay Challenge, станьте первым, кто испытает новую функцию сообщества [Запускать блоки кода онлайн] и выиграйте множество изысканных подарков!
boy illustration
[Техническая посадка травы] Кровавая рвота и отделка позволяют вам необычным образом ощипывать гусиные перья! Не распространяйте информацию! ! !
boy illustration
[Официальное ограниченное по времени мероприятие] Сейчас ноябрь, напишите и получите приз
boy illustration
Прочтите это в одной статье: Учебник для няни по созданию сервера Huanshou Parlu на базе CVM-сервера.
boy illustration
Cloud Native | Что такое CRD (настраиваемые определения ресурсов) в K8s?
boy illustration
Как использовать Cloudflare CDN для настройки узла (CF самостоятельно выбирает IP) Гонконг, Китай/Азия узел/сводка и рекомендации внутреннего высокоскоростного IP-сегмента
boy illustration
Дополнительные правила вознаграждения амбассадоров акции в марте 2023 г.
boy illustration
Можно ли открыть частный сервер Phantom Beast Palu одним щелчком мыши? Супер простой урок для начинающих! (Прилагается метод обновления сервера)
boy illustration
[Играйте с Phantom Beast Palu] Обновите игровой сервер Phantom Beast Pallu одним щелчком мыши
boy illustration
Maotouhu делится: последний доступный внутри страны адрес склада исходного образа Docker 2024 года (обновлено 1 декабря)
boy illustration
Кодирование Base64 в MultipartFile
boy illustration
5 точек расширения SpringBoot, супер практично!
boy illustration
Глубокое понимание сопоставления индексов Elasticsearch.
boy illustration
15 рекомендуемых платформ разработки с нулевым кодом корпоративного уровня. Всегда найдется та, которая вам понравится.
boy illustration
Аннотация EasyExcel позволяет экспортировать с сохранением двух десятичных знаков.