Skip to content

Commit 1ea8506

Browse files
committed
otus #30
1 parent 2dc67c9 commit 1ea8506

13 files changed

+440
-0
lines changed

otus-30/Dockerfile

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
FROM clojure:temurin-20-lein as builder
2+
3+
RUN mkdir /build
4+
5+
WORKDIR /build
6+
7+
COPY src src
8+
COPY project.clj project.clj
9+
COPY entrypoint.sh entrypoint.sh
10+
11+
RUN lein uberjar
12+
13+
14+
15+
FROM eclipse-temurin:20-jdk
16+
17+
RUN mkdir -p /opt/jmx_exporter
18+
RUN wget -O /opt/jmx_exporter/jmx_prometheus_javaagent-0.16.1.jar https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.16.1/jmx_prometheus_javaagent-0.16.1.jar
19+
COPY jmx-config.yaml /opt/jmx_exporter/config.yaml
20+
21+
RUN mkdir -p /opt/elastic-apm
22+
RUN wget -O /opt/elastic-apm/elastic-apm-agent-1.34.1.jar https://search.maven.org/remotecontent?filepath=co/elastic/apm/elastic-apm-agent/1.34.1/elastic-apm-agent-1.34.1.jar
23+
COPY elastic.properties /opt/elastic-apm/elastic.properties
24+
25+
RUN mkdir /service
26+
27+
COPY --from=builder /build/target/production-app.jar /service/production-app.jar
28+
COPY --from=builder /build/entrypoint.sh /service/entrypoint.sh
29+
30+
EXPOSE 8080
31+
32+
ENTRYPOINT ["./service/entrypoint.sh"]

otus-30/Dockerfile.lambda

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
FROM --platform=linux/amd64 clojure:openjdk-11-lein-2.9.5 as builder
2+
3+
RUN mkdir /opt/app
4+
WORKDIR /opt/app
5+
6+
COPY src src
7+
COPY project.clj project.clj
8+
9+
RUN lein uberjar
10+
11+
12+
13+
FROM --platform=linux/amd64 public.ecr.aws/lambda/java:11
14+
15+
RUN mkdir /opt/app
16+
17+
COPY --from=builder /opt/app/target/lambda.jar /opt/app/app.jar
18+
19+
ENTRYPOINT [ "java", "-cp", "/opt/app/app.jar", "com.amazonaws.services.lambda.runtime.api.client.AWSLambda" ]
20+
21+
CMD ["otus-30.lambda::handleRequest"]

otus-30/Dockerfile.simple

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM openjdk:17
2+
3+
WORKDIR /
4+
5+
COPY target/production-app.jar /
6+
7+
CMD java -jar target/production-app.jar

otus-30/README.md

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# otus-30
2+
3+
4+
### Конфигурация для сборки в project.clj
5+
6+
```clojure
7+
:main ^:skip-aot otus-30.core
8+
9+
{:uberjar {:aot :all}}
10+
```
11+
Почитать про компиляцию
12+
https://clojure.org/reference/compilation
13+
14+
15+
### Сборка jar файла
16+
17+
```shell
18+
lein uberjar
19+
```
20+
### Запуск
21+
22+
```shell
23+
java -jar target/production-app.jar
24+
```
25+
26+
27+
### Docker
28+
29+
Сборка Docker образа
30+
31+
```shell
32+
docker build --tag otus-clojure/app:1.1 .
33+
```
34+
Запуск Docker контейнера
35+
36+
```shell
37+
docker run -p 8080:8080 otus-clojure/app
38+
```
39+
40+
41+
### JVM options
42+
43+
https://blogs.oracle.com/javamagazine/post/the-best-hotspot-jvm-options-and-switches-for-java-11-through-java-17
44+
45+
- -XX:InitialRAMPercentage
46+
- -XX:MaxRAMPercentage
47+
- -XX:+UseSerialGC
48+
- -XX:+UseParallelGC
49+
- -XX:+UseZGC
50+
- -XX:+UnlockExperimentalVMOptions
51+
- -XX:+UseContainerSupport
52+
53+
54+
### Логирование
55+
56+
Java logging frameworks
57+
https://lambdaisland.com/blog/2020-06-12-logging-in-clojure-making-sense-of-the-mess
58+
59+
Pure Clojure logging
60+
https://github.com/BrunoBonacci/mulog
61+
62+
63+
### Сбор JMX метрик
64+
65+
https://github.com/prometheus/jmx_exporter
66+
https://opentelemetry.io/docs/collector
67+
https://prometheus.io
68+
69+
70+
### Сборка проекта с помощью GraalVM
71+
72+
https://github.com/graalvm/graalvm-ce-builds/releases
73+
https://github.com/clj-easy/graalvm-clojure/tree/master/
74+
75+
```shell
76+
lein do clean, uberjar
77+
78+
native-image --report-unsupported-elements-at-runtime \
79+
--initialize-at-build-time \
80+
--no-server \
81+
-jar ./target/production-app.jar \
82+
-H:Name=./target/hello-world
83+
84+
./target/hello-world
85+
```
86+
87+
```shell
88+
time java -jar ./target/production-app.jar
89+
90+
time ./target/hello-world
91+
```
92+
93+
94+
### AWS Lambda
95+
96+
Required Java interface
97+
https://github.com/aws/aws-lambda-java-libs/blob/main/aws-lambda-java-runtime-interface-client/README.md
98+
99+
100+
101+
## Homework
102+
103+
Применить принципы hexagonal architecture в проекте на выбор (Pokemon app)
104+
105+
### Задание
106+
107+
- Разделить код проекта на доменные модули
108+
- Выделить в сервисы код взаимодействующий с внешними системами
109+
- Подключить к проекту фреймворк Duct
110+
- Написать конфигурации для двух режимов запуска приложения (dev, production)
111+
- Применить dependency injection для тестирования логики приложения
112+
- Настроить production сборку для проекта
113+
- Создать Dockerfile для сборки и запуска
114+
- Создать entrypoint.sh фаил
115+
- Настроить логирование и сборку метрик (JMX)

otus-30/elastic.properties

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# https://www.elastic.co/guide/en/apm/agent/java/master/config-reference-properties-file.html
2+
3+
############################################
4+
# Circuit-Breaker #
5+
############################################
6+
7+
circuit_breaker_enabled=false
8+
9+
############################################
10+
# Core #
11+
############################################
12+
13+
recording=true
14+
enabled=true
15+
instrument=true
16+
transaction_sample_rate=1
17+
transaction_max_spans=500
18+
sanitize_field_names=password,passwd,pwd,secret,*key,*token*,*session*,*credit*,*card*,*auth*,*principal*,set-cookie
19+
enable_experimental_instrumentations=false
20+
capture_body=ALL
21+
capture_headers=true
22+
central_config=true
23+
breakdown_metrics=true
24+
config_file=_AGENT_HOME_/elasticapm.properties
25+
use_elastic_traceparent_header=true
26+
span_min_duration=0ms
27+
cloud_provider=AWS
28+
enable_public_api_annotation_inheritance=false
29+
trace_continuation_strategy=CONTINUE
30+
31+
############################################
32+
# HTTP #
33+
############################################
34+
35+
capture_body_content_types=application/x-www-form-urlencoded*,text/*,application/json*,application/xml*
36+
transaction_ignore_urls=/VAADIN/*,*/healthcheck,/heartbeat*,/favicon.ico,*.js,*.css,*.jpg,*.jpeg,*.png,*.gif,*.webp,*.svg,*.woff,*.woff2
37+
use_path_as_transaction_name=true
38+
39+
############################################
40+
# Huge Traces #
41+
############################################
42+
43+
span_compression_enabled=true
44+
span_compression_exact_match_max_duration=50ms
45+
span_compression_same_kind_max_duration=0ms
46+
exit_span_min_duration=0ms
47+
48+
############################################
49+
# JAX-RS #
50+
############################################
51+
52+
enable_jaxrs_annotation_inheritance=false
53+
use_jaxrs_path_as_transaction_name=false
54+
55+
############################################
56+
# JMX #
57+
############################################
58+
59+
capture_jmx_metrics=\
60+
object_name[java.lang:type=Memory] \
61+
attribute[HeapMemoryUsage:metric_name=heap] \
62+
attribute[NonHeapMemoryUsage:metric_name=nonheap] \
63+
, \
64+
object_name[java.lang:type=Threading] \
65+
attribute[ThreadCount:metric_name=thread_count]
66+
67+
############################################
68+
# Logging #
69+
############################################
70+
71+
log_level=INFO
72+
log_file=System.out
73+
log_ecs_reformatting=OFF
74+
log_format_file=JSON
75+
76+
############################################
77+
# Metrics #
78+
############################################
79+
80+
dedot_custom_metrics=true
81+
metric_set_limit=1000
82+
83+
############################################
84+
# Profiling #
85+
############################################
86+
87+
profiling_inferred_spans_enabled=false
88+
profiling_inferred_spans_sampling_interval=50ms
89+
profiling_inferred_spans_min_duration=0ms
90+
profiling_inferred_spans_included_classes=*
91+
profiling_inferred_spans_excluded_classes=(?-i)java.*,(?-i)javax.*,(?-i)sun.*,(?-i)com.sun.*,(?-i)jdk.*,(?-i)org.apache.tomcat.*,(?-i)org.apache.catalina.*,(?-i)org.apache.coyote.*,(?-i)org.jboss.as.*,(?-i)org.glassfish.*,(?-i)org.eclipse.jetty.*,(?-i)com.ibm.websphere.*,(?-i)io.undertow.*
92+
93+
############################################
94+
# Reporter #
95+
############################################
96+
97+
disable_send=false
98+
server_timeout=5s
99+
verify_server_cert=true
100+
max_queue_size=512
101+
include_process_args=false
102+
api_request_time=10s
103+
api_request_size=768kb
104+
metrics_interval=30s
105+
106+
############################################
107+
# Stacktrace #
108+
############################################
109+
110+
application_packages=otus-30.core
111+
stack_trace_limit=50
112+
span_stack_trace_min_duration=0ms

otus-30/entrypoint.sh

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/bin/bash
2+
3+
APP_NAME=otus-app
4+
JAR_PATH=/service/production-app.jar
5+
ENVIRONMENT=dev
6+
7+
# Sets initial values of variables
8+
PWD="$(dirname "$0")"
9+
LOG_DIR="$PWD/log"
10+
EC2_INSTANCE=$(hostname)
11+
12+
export MALLOC_ARENA_MAX=4
13+
# Stop the JVM from being allowed to use up all of
14+
# Docker's virtual memory. Use if it's a problem
15+
# see https://siddhesh.in/posts/malloc-per-thread-arenas-in-glibc.html
16+
17+
set -eu
18+
19+
trap 'error_handler' ERR 1 2 3 4 5 6
20+
21+
error_handler() {
22+
ERROR_CODE=$?
23+
echo "App crashed: $ERROR_CODE"
24+
exit $ERROR_CODE
25+
}
26+
27+
cd $PWD
28+
29+
# JMX prometheus exporter javaagent configuration
30+
JMX_OPTS="-javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent-0.16.1.jar=8080:/opt/jmx_exporter/config.yaml"
31+
32+
# APM Elastic javaagent configuration
33+
APM_OPTS="-javaagent:/opt/elastic-apm/elastic-apm-agent-1.34.1.jar \
34+
-Delastic.apm.service_name=${APP_NAME} \
35+
-Delastic.apm.server_urls=${APM_HOST} \
36+
-Delastic.apm.secret_token=${APM_SECRET_TOKEN} \
37+
-Delastic.apm.environment=${ENVIRONMENT} \
38+
-Delastic.apm.config_file=/opt/elastic-apm/elastic.properties"
39+
40+
# JVM options
41+
JAVA_OPTS="-XX:InitialRAMPercentage=30 -XX:MaxRAMPercentage=85 -XX:+UseContainerSupport -XshowSettings:system "
42+
43+
java $APM_OPTS \
44+
$JMX_OPTS \
45+
$JAVA_OPTS \
46+
-jar $JAR_PATH "$@"

otus-30/jmx-config.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
rules:
2+
- pattern: ".*"

otus-30/logfile.log

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
18:57:29.592 [nREPL-session-b875359f-f3ce-40e2-a7a2-262c387ec591] INFO otus-30.core - Hello world
2+
19:01:07.245 [nREPL-session-b875359f-f3ce-40e2-a7a2-262c387ec591] WARN otus-30.core - Hello world
3+
19:01:15.257 [nREPL-session-b875359f-f3ce-40e2-a7a2-262c387ec591] ERROR otus-30.core - Hello world

otus-30/project.clj

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
(defproject otus-30 "0.1.0-SNAPSHOT"
2+
3+
:dependencies [[org.clojure/clojure "1.11.1"]
4+
5+
[org.slf4j/slf4j-api "1.7.32"]
6+
[ch.qos.logback/logback-classic "1.2.6"]
7+
[org.clojure/tools.logging "1.2.4"]
8+
9+
[com.brunobonacci/mulog "0.9.0"]
10+
11+
[nrepl "0.9.0"]
12+
13+
[com.amazonaws/aws-lambda-java-runtime-interface-client "2.4.0"]]
14+
15+
16+
17+
:uberjar-name "production-app.jar"
18+
19+
:main ^:skip-aot otus-30.core
20+
21+
:repl-options {:init-ns otus-30.core}
22+
23+
:profiles {:uberjar {:aot :all}})

otus-30/resources/logback.xml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<configuration>
2+
<!-- Console Appender -->
3+
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
4+
<encoder>
5+
<pattern>%d{HH:mm:ss.SSS} YOHOHO %-5level %logger{36} - %msg%n</pattern>
6+
</encoder>
7+
</appender>
8+
9+
<!-- File Appender -->
10+
<appender name="file" class="ch.qos.logback.core.FileAppender">
11+
<file>logfile.log</file>
12+
<encoder>
13+
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
14+
</encoder>
15+
</appender>
16+
17+
<!-- disable the pedestal cors logs to mess the log -->
18+
<logger name="io.pedestal.http.cors" level="WARN"/>
19+
20+
<root level="info">
21+
<appender-ref ref="console"/>
22+
<appender-ref ref="file"/>
23+
</root>
24+
</configuration>

0 commit comments

Comments
 (0)