├── .gitattributes
├── .gitignore
├── README-en.md
├── README.md
├── docker
├── README.md
├── build-basis.sh
├── deploy-basis.sh
├── deploy-mydemo.sh
├── docker-compose.yml
├── java
│ ├── Dockerfile
│ └── build.sh
├── mycat
│ ├── Dockerfile
│ ├── README.md
│ ├── build.sh
│ ├── run.sh
│ └── scripts
│ │ ├── bin
│ │ ├── docker-entrypoint.sh
│ │ └── startup_nowrap.sh
│ │ └── conf
│ │ ├── order-partition.txt
│ │ ├── rule.xml
│ │ ├── schema.xml
│ │ ├── sequence_db_conf.properties
│ │ ├── server.xml
│ │ └── user-partition.txt
├── mysql
│ ├── Dockerfile
│ ├── build.sh
│ ├── run.sh
│ └── scripts
│ │ ├── 1-mydemo.sql
│ │ ├── 2-nacos.sql
│ │ ├── 3-seata.sql
│ │ ├── 4-zipkin.sql
│ │ ├── 5-skywalking.sql
│ │ ├── 9-users.sql
│ │ └── my.cnf
├── nacos
│ ├── Dockerfile
│ ├── build.sh
│ ├── run.sh
│ └── scripts
│ │ └── init.sh
├── seata
│ ├── Dockerfile
│ ├── build.sh
│ ├── run.sh
│ └── scripts
│ │ ├── bin
│ │ └── seata-server.sh
│ │ └── conf
│ │ ├── config.txt
│ │ ├── init.sh
│ │ ├── nacos-config.sh
│ │ └── registry.conf
├── shardingproxy
│ ├── Dockerfile
│ ├── build.sh
│ ├── run.sh
│ └── scripts
│ │ ├── bin
│ │ └── docker-entrypoint.sh
│ │ └── conf
│ │ ├── config-order.yaml
│ │ ├── config-user.yaml
│ │ └── server.yaml
├── skywalking
│ ├── README.md
│ ├── base
│ │ ├── Dockerfile
│ │ ├── build.sh
│ │ └── configs
│ │ │ ├── config
│ │ │ ├── application.yml
│ │ │ └── log4j2.xml
│ │ │ ├── oap.sh
│ │ │ ├── ui.sh
│ │ │ └── webapp
│ │ │ └── webapp.yml
│ ├── build.sh
│ ├── client
│ │ ├── Dockerfile
│ │ └── build.sh
│ ├── oap
│ │ ├── Dockerfile
│ │ ├── build.sh
│ │ └── run.sh
│ ├── run.sh
│ └── ui
│ │ ├── Dockerfile
│ │ ├── build.sh
│ │ └── run.sh
└── zipkin
│ ├── Dockerfile
│ ├── build.sh
│ ├── quickstart.sh
│ └── run.sh
├── docs
├── APM-PinPoint.md
├── APM-SkyWalking.md
├── APM-ZipKin.md
├── Dubbo-basis.md
├── Seata-Distributed-Transaction-Management.md
├── Sharding-DRDS-Overview.md
├── Sharding-Mycat-Overview-Quickstart.md
├── Sharding-Sharding-Proxy-Overview-Quickstart.md
├── images
│ ├── architecture.png
│ ├── db-sharding-1.png
│ ├── db-sharding-2.png
│ ├── docker-containers.png
│ ├── docker-download-curl.png
│ ├── docker-download-wget.png
│ ├── docker-stats.png
│ ├── kubernetes-overview.png
│ ├── mycat-explain.png
│ ├── newman-output.jpg
│ ├── order-service-out.png
│ ├── postman.jpg
│ ├── shopweb-out.png
│ └── table-schema.png
└── source.pptx
├── fitnesse
├── Dockerfile
├── build.sh
├── fitnesse-standalone.jar
├── pom.xml
├── run.sh
└── src
│ └── main
│ ├── java
│ └── my
│ │ └── demo
│ │ └── test
│ │ ├── DbUtils.java
│ │ ├── Manager.java
│ │ └── fixture
│ │ ├── DeleteUserFromDb.java
│ │ ├── ItemQueryTest.java
│ │ ├── UserRegisterAndLoginDetailTest.java
│ │ └── UserRegisterAndLoginSummaryTest.java
│ └── resources
│ ├── application.yml
│ └── logback.xml
├── istio
├── deploy-istio.sh
├── deployment
│ ├── mycat-statefulset.yaml
│ ├── mysql-statefulset.yaml
│ ├── nacos-statefulset.yaml
│ ├── svc-item-deployment.yaml
│ ├── svc-order-deployment.yaml
│ ├── svc-stock-deployment.yaml
│ ├── svc-user-deployment.yaml
│ ├── web-shop-deployment.yaml
│ └── zipkin-statefulset.yaml
└── undeploy-istio.sh
├── item-service
├── Dockerfile.default
├── Dockerfile.skywalking
├── build.sh
├── docker-entrypoint.sh
├── pom.xml
├── run.sh
└── src
│ └── main
│ ├── java
│ └── my
│ │ └── demo
│ │ └── service
│ │ └── item
│ │ ├── Application.java
│ │ └── ItemServiceImpl.java
│ └── resources
│ ├── application.yml
│ └── logback.xml
├── k8s
├── deploy-k8s.sh
├── deployment
│ ├── mycat-statefulset.yaml
│ ├── mysql-statefulset.yaml
│ ├── nacos-statefulset.yaml
│ ├── svc-item-deployment.yaml
│ ├── svc-order-deployment.yaml
│ ├── svc-stock-deployment.yaml
│ ├── svc-user-deployment.yaml
│ ├── web-shop-deployment.yaml
│ └── zipkin-statefulset.yaml
├── install
│ ├── images.properties
│ └── load_images.sh
└── undeploy-k8s.sh
├── order-service
├── Dockerfile.default
├── Dockerfile.skywalking
├── build.sh
├── docker-entrypoint.sh
├── pom.xml
├── run.sh
└── src
│ └── main
│ ├── java
│ └── my
│ │ └── demo
│ │ ├── dao
│ │ └── order
│ │ │ └── OrderDao.java
│ │ └── service
│ │ └── order
│ │ ├── Application.java
│ │ └── OrderServiceImpl.java
│ └── resources
│ ├── application.yml
│ ├── logback.xml
│ └── mappers
│ └── OrderMapper.xml
├── package.sh
├── pom.xml
├── postman
├── README.md
├── build.sh
├── newman
│ ├── Dockerfile
│ ├── docker-env.postman_environment.json
│ ├── k8s-env.postman_environment.json
│ ├── local-env.postman_environment.json
│ └── mydemo.postman_collection.json
├── nodejs
│ └── Dockerfile
├── run.sh
└── xmysql
│ ├── Dockerfile
│ └── entrypoint.sh
├── selenium
├── pom.xml
├── selenium-ide-project.side
└── src
│ └── main
│ └── java
│ └── my
│ └── demo
│ └── test
│ └── selenium
│ └── RegisterTest.java
├── service-client
├── pom.xml
└── src
│ └── main
│ └── java
│ └── my
│ └── demo
│ ├── entity
│ ├── Cart.java
│ ├── CartItem.java
│ ├── Item.java
│ ├── Order.java
│ ├── OrderItem.java
│ ├── Stock.java
│ ├── User.java
│ └── UserAccount.java
│ ├── service
│ ├── HelloService.java
│ ├── ItemService.java
│ ├── OrderService.java
│ ├── ServiceResult.java
│ ├── StockService.java
│ └── UserService.java
│ └── utils
│ ├── DruidConfiguration.java
│ ├── DruidProperties.java
│ ├── MyDemoUtils.java
│ ├── SeataConfiguration.java
│ ├── ZipkinConfiguration.java
│ └── ZipkinProperties.java
├── shop-web
├── Dockerfile.default
├── Dockerfile.skywalking
├── build.sh
├── docker-entrypoint.sh
├── pom.xml
├── run.sh
└── src
│ └── main
│ ├── java
│ └── my
│ │ └── demo
│ │ └── web
│ │ ├── Application.java
│ │ ├── HelloController.java
│ │ ├── ShopController.java
│ │ └── TestResult.java
│ └── resources
│ ├── application-zipkin.yml
│ ├── application.yml
│ ├── logback.xml
│ ├── static
│ ├── button.css
│ ├── jquery.js
│ └── main.css
│ └── templates
│ └── home.html
├── stock-service
├── Dockerfile.default
├── Dockerfile.skywalking
├── build.sh
├── docker-entrypoint.sh
├── pom.xml
├── run.sh
└── src
│ └── main
│ ├── java
│ └── my
│ │ └── demo
│ │ └── service
│ │ └── stock
│ │ ├── Application.java
│ │ └── StockServiceImpl.java
│ └── resources
│ ├── application.yml
│ └── logback.xml
└── user-service
├── Dockerfile.default
├── Dockerfile.skywalking
├── build.sh
├── docker-entrypoint.sh
├── pom.xml
├── run.sh
└── src
├── main
├── java
│ └── my
│ │ └── demo
│ │ ├── dao
│ │ └── user
│ │ │ └── UserDao.java
│ │ └── service
│ │ └── user
│ │ ├── Application.java
│ │ ├── HelloServiceImpl.java
│ │ └── UserServiceImpl.java
└── resources
│ ├── application.yml
│ ├── logback.xml
│ └── mappers
│ └── UserMapper.xml
└── test
└── java
└── my
└── demo
└── service
└── user
└── test
└── UserServiceImplTest.java
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.css linguist-vendored
2 | *.js linguist-vendored
3 | *.html linguist-vendored
4 | *.xml linguist-vendored
5 | *.sh linguist-vendored
6 | docs/* linguist-vendored
7 | docker/* linguist-vendored
8 | k8s/* linguist-vendored
9 | istio/* linguist-vendored
10 | postman/* linguist-vendored
11 | fitnesse/* linguist-vendored
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | **/target/
2 | **/.settings
3 | **/.project
4 | **/.classpath
5 | **/.DS_Store
6 | **/test-output
7 |
--------------------------------------------------------------------------------
/docker/README.md:
--------------------------------------------------------------------------------
1 | #### Comments on building docker images
2 | 1. For java applications, `openjdk:8-jre-alpine` is a better choice for base images.
3 | - `openjdk:8`: OS is Debian 10.2, image size: **510MB**;
4 | - `openjdk:8-jre-alpine`: OS is Alpine Linux, image size: **84.9MB**;
5 | 2. Use `curl` instead of `wget` to download to avoid progress status issues.
6 | - `curl`:
7 | 
8 | - `wget`:
9 | 
10 | 3. In some cases [multi-stage builds](https://docs.docker.com/develop/develop-images/multistage-build/) is a very
11 | convenient way to build images for 3-party/complicated applications, see [docker/skywalking](skywalking/) for an example.
12 |
--------------------------------------------------------------------------------
/docker/build-basis.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd `dirname "$0"`
4 | BASE_DIR=`pwd`
5 |
6 | set -e
7 |
8 | ./mysql/build.sh
9 |
10 | ./java/build.sh
11 |
12 | ./mycat/build.sh
13 |
14 | ./shardingproxy/build.sh
15 |
16 | ./nacos/build.sh
17 |
18 | ./seata/build.sh
19 |
20 | ./skywalking/build.sh
21 |
22 | ./zipkin/build.sh
23 |
--------------------------------------------------------------------------------
/docker/deploy-basis.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd `dirname "$0"`
4 | BASE_DIR=`pwd`
5 |
6 | set -e
7 |
8 | docker network create mydemo
9 |
10 | ./mysql/run.sh
11 |
12 | ./mycat/run.sh
13 |
14 | ./shardingproxy/run.sh
15 |
16 | ./nacos/run.sh
17 |
18 | ./seata/run.sh
19 |
20 | ./skywalking/run.sh
21 |
22 | ./zipkin/run.sh
23 |
24 |
--------------------------------------------------------------------------------
/docker/deploy-mydemo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | show_usage() {
4 | echo " Usage:"
5 | echo " -build: Build images for item, stock, user, order services and shop-web app."
6 | echo " -run: Run containers for item, stock, user, order services and shop-web app."
7 | echo " -stop: Stop containers for item, stock, user, order services and shop-web app."
8 | echo " -rm: Remove containers for item, stock, user, order services and shop-web app."
9 | echo " -rmi: Remove images for item, stock, user, order services and shop-web app."
10 | }
11 |
12 | if [ $# -eq 0 ]; then
13 | show_usage
14 | exit 0
15 | fi;
16 |
17 | DOCKER=`dirname "$0"`
18 | cd $DOCKER
19 | DOCKER=`pwd`
20 | cd $DOCKER/../
21 | PROJECT_HOME=`pwd`
22 |
23 | while [ -n "$1" ]
24 | do
25 | case "$1" in
26 | -build|--build)
27 | $PROJECT_HOME/item-service/build.sh;
28 | $PROJECT_HOME/stock-service/build.sh;
29 | $PROJECT_HOME/user-service/build.sh;
30 | $PROJECT_HOME/order-service/build.sh;
31 | $PROJECT_HOME/shop-web/build.sh;
32 | shift 1;;
33 | -run|--run)
34 | $PROJECT_HOME/item-service/run.sh;
35 | $PROJECT_HOME/stock-service/run.sh;
36 | $PROJECT_HOME/user-service/run.sh;
37 | $PROJECT_HOME/order-service/run.sh;
38 | $PROJECT_HOME/shop-web/run.sh;
39 | shift 1;;
40 | -start|--start)
41 | docker start item stock user order shopweb;
42 | shift 1;;
43 | -stop|--stop)
44 | docker stop shopweb order user stock item;
45 | shift 1;;
46 | -rmi|--rmi)
47 | docker rmi mydemo/shopweb mydemo/order mydemo/user mydemo/stock mydemo/item;
48 | shift 1;;
49 | -rm|--rm)
50 | docker rm shopweb order user stock item;
51 | shift 1;;
52 | ?|-?|-help|--help) show_usage; exit 0;;
53 | --) break;;
54 | *) echo " Invalid parameter: $1"; show_usage; exit 1;;
55 | esac
56 | done
57 |
--------------------------------------------------------------------------------
/docker/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | mysql:
4 | image: "mydemo/mysql:5.7.18"
5 | container_name: mysql
6 | networks:
7 | - mydemo
8 | ports:
9 | - target: 3306
10 | published: 13306
11 | environment:
12 | MYSQL_ROOT_PASSWORD: 123
13 |
14 | nacos:
15 | image: "mydemo/nacos:1.1.4"
16 | container_name: nacos
17 | networks:
18 | - mydemo
19 | ports:
20 | - "18848:8848"
21 | environment:
22 | MYSQL_HOST: mysql
23 | depends_on:
24 | - mysql
25 |
26 | mycat:
27 | image: "mydemo/mycat:1.6.7.3"
28 | container_name: mycat
29 | networks:
30 | - mydemo
31 | ports:
32 | - "18066:8066"
33 | - "19066:9066"
34 | environment:
35 | MYSQL_HOST: mysql
36 | depends_on:
37 | - mysql
38 |
39 | # shardingproxy:
40 | # image: "mydemo/shardingproxy:4.0.0-RC3"
41 | # container_name: shardingproxy
42 | # networks:
43 | # - mydemo
44 | # ports:
45 | # - "13307:3307"
46 | # environment:
47 | # MYSQL_HOST: mysql
48 | # depends_on:
49 | # - mysql
50 |
51 | zipkin:
52 | image: "mydemo/zipkin:2.19.2"
53 | container_name: zipkin
54 | networks:
55 | - mydemo
56 | ports:
57 | - "19411:9411"
58 | environment:
59 | MYSQL_HOST: mysql
60 | depends_on:
61 | - mysql
62 |
63 | item:
64 | image: "mydemo/item"
65 | container_name: item
66 | networks:
67 | - mydemo
68 | environment:
69 | SERVICE_HOST: item
70 | NACOS_HOST: nacos
71 | ZIPKIN_HOST: zipkin
72 | SKYWALKING_HOST: skywalking-oap
73 | depends_on:
74 | - nacos
75 | - mycat
76 | # - shardingproxy
77 | - zipkin
78 |
79 | stock:
80 | image: "mydemo/stock"
81 | container_name: stock
82 | networks:
83 | - mydemo
84 | environment:
85 | SERVICE_HOST: stock
86 | NACOS_HOST: nacos
87 | ZIPKIN_HOST: zipkin
88 | SKYWALKING_HOST: skywalking-oap
89 | depends_on:
90 | - nacos
91 | - mycat
92 | # - shardingproxy
93 | - zipkin
94 |
95 | user:
96 | image: "mydemo/user"
97 | container_name: user
98 | networks:
99 | - mydemo
100 | environment:
101 | SERVICE_HOST: user
102 | MYSQL_HOST: mysql # mycat, shardingproxy
103 | NACOS_HOST: nacos
104 | ZIPKIN_HOST: zipkin
105 | SKYWALKING_HOST: skywalking-oap
106 | depends_on:
107 | - nacos
108 | - mycat
109 | # - shardingproxy
110 | - zipkin
111 |
112 | order:
113 | image: "mydemo/order"
114 | container_name: order
115 | networks:
116 | - mydemo
117 | environment:
118 | SERVICE_HOST: order
119 | NACOS_HOST: nacos
120 | ZIPKIN_HOST: zipkin
121 | SKYWALKING_HOST: skywalking-oap
122 | depends_on:
123 | - item
124 | - stock
125 |
126 | shopweb:
127 | image: "mydemo/shopweb"
128 | container_name: shopweb
129 | networks:
130 | - mydemo
131 | ports:
132 | - "18090:8090"
133 | environment:
134 | SERVICE_HOST: shopweb
135 | NACOS_HOST: nacos
136 | ZIPKIN_HOST: zipkin
137 | SKYWALKING_HOST: skywalking-oap
138 | depends_on:
139 | - item
140 | - user
141 | - order
142 |
143 | networks:
144 | mydemo:
145 |
--------------------------------------------------------------------------------
/docker/java/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM openjdk:8-jre-alpine
2 |
3 | # Change Alpine Linux apk source to mirror site in China.
4 | RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories && apk add --no-cache bash dos2unix curl busybox-extras
5 |
--------------------------------------------------------------------------------
/docker/java/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd `dirname "$0"`
4 |
5 | echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
6 | echo ">>> Build an openjdk image as the parent image for those run a java application."
7 | echo ">>> It download openjdk from Docker Hub, and install some shell packages (VERY SLOW)."
8 | echo ">>> Please wait ... "
9 | docker build -t mydemo/openjdk:8-jre-alpine .
10 | echo "<<< Finished: mydemo/openjdk:8-jre-alpine"
--------------------------------------------------------------------------------
/docker/mycat/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mydemo/openjdk:8-jre-alpine
2 |
3 | # Download Mycat
4 | RUN curl -fL -o /home/mycat.tar.gz http://dl.mycat.org.cn/1.6.7.3/20190927161129/Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz \
5 | && tar xzf /home/mycat.tar.gz -C /home/ \
6 | && rm -rf /home/mycat.tar.gz
7 | WORKDIR /home/mycat
8 | ADD ./scripts/ ./
9 | # sh files with Windows format can't run in container (Alpine Linux), transform to unix format
10 | RUN dos2unix bin/docker-entrypoint.sh && dos2unix bin/startup_nowrap.sh
11 |
12 | ENV MYSQL_HOST=mysql MYSQL_PORT=3306 MYSQL_USER=mydemo MYSQL_PSW=mydemo
13 | EXPOSE 8066 9066
14 | ENTRYPOINT ["bash", "bin/docker-entrypoint.sh"]
15 |
--------------------------------------------------------------------------------
/docker/mycat/README.md:
--------------------------------------------------------------------------------
1 | `docker-entrypoint.sh`: Load MySQL configurations from environment variables, and start mycat server in foreground mode.
2 |
3 | #### Run Mycat in foreground mode
4 | - `FROM openjdk:8`: OS is `Debian 10.2`, Use `bin/mycat console` to run in foreground mode.
5 | - `FROM openjdk:8-jre-alpine`: OS is `Alpine Linux`, `bin/mycat console` throws the following exceptions:
6 | ```
7 | Unable to locate any of the following operational binaries:
8 | /home/mycat/bin/./wrapper-linux-x86-64 (Found but not executable.)
9 | /home/mycat/bin/./wrapper-linux-x86-32 (Found but not executable.)
10 | /home/mycat/bin/./wrapper
11 | ```
12 | Use `bin/startup_nowrap.sh` to avoid this error.
13 | - `bin/startup_nowrap.sh`:
14 | 1. Remove `JAVA_OPTS` to reduce memory allocations.
15 | 2. Change from daemon mode to foreground mode.
--------------------------------------------------------------------------------
/docker/mycat/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd `dirname "$0"`
4 |
5 | echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
6 | echo ">>> Build Mycat image"
7 | docker build -t mydemo/mycat:1.6.7.3 .
8 | echo "<<< Finished: mydemo/mycat:1.6.7.3"
--------------------------------------------------------------------------------
/docker/mycat/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | docker run -d --net=mydemo --name mycat -p 18066:8066 -p 19066:9066 -e MYSQL_HOST=mysql mydemo/mycat:1.6.7.3
--------------------------------------------------------------------------------
/docker/mycat/scripts/bin/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | MYCAT_HOME=`dirname "$0"`
4 | cd $MYCAT_HOME/..
5 | MYCAT_HOME=`pwd`
6 |
7 | if [[ -z "$MYSQL_HOST" || -z "$MYSQL_PORT" || -z "$MYSQL_USER" || -z "$MYSQL_PSW" ]]; then
8 | echo "ENV: MYSQL_HOST, MYSQL_PORT, MYSQL_USER or MYSQL_PSW is empty"
9 | exit 1
10 | fi
11 |
12 | sed -i "s/host=\"[^\"]*\"/host=\"$MYSQL_HOST\"/g" $MYCAT_HOME/conf/schema.xml
13 | sed -i "s/url=\"[^\"]*\"/url=\"$MYSQL_HOST:$MYSQL_PORT\"/g" $MYCAT_HOME/conf/schema.xml
14 | sed -i "s/user=\"[^\"]*\"/user=\"$MYSQL_USER\"/g" $MYCAT_HOME/conf/schema.xml
15 | sed -i "s/password=\"[^\"]*\"/password=\"$MYSQL_PSW\"/g" $MYCAT_HOME/conf/schema.xml
16 |
17 | $MYCAT_HOME/bin/startup_nowrap.sh
--------------------------------------------------------------------------------
/docker/mycat/scripts/bin/startup_nowrap.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #check JAVA_HOME & java
4 | noJavaHome=false
5 | if [ -z "$JAVA_HOME" ] ; then
6 | noJavaHome=true
7 | fi
8 | if [ ! -e "$JAVA_HOME/bin/java" ] ; then
9 | noJavaHome=true
10 | fi
11 | if $noJavaHome ; then
12 | echo
13 | echo "Error: JAVA_HOME environment variable is not set."
14 | echo
15 | exit 1
16 | fi
17 | #==============================================================================
18 | #set JAVA_OPTS
19 | JAVA_OPTS=""
20 | #JAVA_OPTS="-server -Xms4G -Xmx4G -XX:+AggressiveOpts -XX:MaxDirectMemorySize=6G"
21 | #performance Options
22 | #JAVA_OPTS="$JAVA_OPTS -Xss256k"
23 | #JAVA_OPTS="$JAVA_OPTS -XX:+AggressiveOpts"
24 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseBiasedLocking"
25 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseFastAccessorMethods"
26 | #JAVA_OPTS="$JAVA_OPTS -XX:+DisableExplicitGC"
27 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseParNewGC"
28 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC"
29 | #JAVA_OPTS="$JAVA_OPTS -XX:+CMSParallelRemarkEnabled"
30 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseCMSCompactAtFullCollection"
31 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseCMSInitiatingOccupancyOnly"
32 | #JAVA_OPTS="$JAVA_OPTS -XX:CMSInitiatingOccupancyFraction=75"
33 | #JAVA_OPTS="$JAVA_OPTS -XX:CMSInitiatingOccupancyFraction=75"
34 | #GC Log Options
35 | #JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCApplicationStoppedTime"
36 | #JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCTimeStamps"
37 | #JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails"
38 | #debug Options
39 | #JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=8065,server=y,suspend=n"
40 | #==============================================================================
41 |
42 | #set HOME
43 | CURR_DIR=`pwd`
44 | cd `dirname "$0"`/..
45 | MYCAT_HOME=`pwd`
46 | cd $CURR_DIR
47 | if [ -z "$MYCAT_HOME" ] ; then
48 | echo
49 | echo "Error: MYCAT_HOME environment variable is not defined correctly."
50 | echo
51 | exit 1
52 | fi
53 | #==============================================================================
54 |
55 | #set CLASSPATH
56 | MYCAT_CLASSPATH="$MYCAT_HOME/conf:$MYCAT_HOME/lib/classes"
57 | for i in "$MYCAT_HOME"/lib/*.jar
58 | do
59 | MYCAT_CLASSPATH="$MYCAT_CLASSPATH:$i"
60 | done
61 | #==============================================================================
62 |
63 | #startup Server
64 | RUN_CMD="java"
65 | RUN_CMD="$RUN_CMD -DMYCAT_HOME=$MYCAT_HOME"
66 | RUN_CMD="$RUN_CMD -classpath $MYCAT_CLASSPATH"
67 | RUN_CMD="$RUN_CMD $JAVA_OPTS"
68 | RUN_CMD="$RUN_CMD io.mycat.MycatStartup $@"
69 | # RUN_CMD="$RUN_CMD >> \"$MYCAT_HOME/logs/console.log\" 2>&1 &"
70 | echo $RUN_CMD
71 | $RUN_CMD
72 | #==============================================================================
73 |
--------------------------------------------------------------------------------
/docker/mycat/scripts/conf/order-partition.txt:
--------------------------------------------------------------------------------
1 | 0-7=0
2 | 8-15=1
3 | 16-23=2
4 | 24-31=3
5 |
--------------------------------------------------------------------------------
/docker/mycat/scripts/conf/rule.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
14 | order_id
15 | order-func
16 |
17 |
18 |
19 |
20 | user_id
21 | user-order-func
22 |
23 |
24 |
25 |
26 | user_id
27 | user-func
28 |
29 |
30 |
31 |
32 | account_hash
33 | user-account-func
34 |
35 |
36 |
37 |
38 | 32
39 | order-partition.txt
40 |
41 |
42 | 32
43 | order-partition.txt
44 |
45 |
46 | 32
47 | user-partition.txt
48 |
49 |
50 | 2
51 |
52 |
53 |
--------------------------------------------------------------------------------
/docker/mycat/scripts/conf/schema.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
48 |
49 | select user()
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/docker/mycat/scripts/conf/sequence_db_conf.properties:
--------------------------------------------------------------------------------
1 | #sequence stored in datanode
2 | GLOBAL=dn0
3 | ORD_ORDER_ITEM=dn0
4 | ORD_USER_ORDER=dn0
5 | USR_USER=dn0
--------------------------------------------------------------------------------
/docker/mycat/scripts/conf/server.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 | 0
14 | 1
15 | 0
16 | 0
17 |
18 |
19 | 1
20 |
21 | false
22 |
23 | 0
24 |
25 | 0
26 | 1
27 | 64k
28 | 1k
29 | 0
30 | 384m
31 |
32 | false
33 |
34 | false
35 |
36 | 3600000
37 | 3
38 | 2
39 |
40 |
41 | 3600000
42 |
43 | 10000
44 |
45 | 3600000
46 |
47 |
48 |
49 |
50 | mydemo
51 | db_user,db_order
52 |
53 |
--------------------------------------------------------------------------------
/docker/mycat/scripts/conf/user-partition.txt:
--------------------------------------------------------------------------------
1 | 0-15=0
2 | 16-31=1
3 |
--------------------------------------------------------------------------------
/docker/mysql/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mysql:5.7.18
2 |
3 | ENV LANG=C.UTF-8
4 | # Database Initialization: Put the *.sql、*.sh scrips into /docker-entrypoint-initdb.d/ directory
5 | # 1-app-schema.sql:Schemas for demo application
6 | # 2-nacos-mysql.sql: Schemas for Nacos
7 | # 9-users.sql:Users and privileges required by demo application middlewares
8 | ADD ./scripts/*.sql /docker-entrypoint-initdb.d/
9 | # Location of MySQL configuration files:
10 | # /etc/my.cnf
11 | # /etc/mysql/conf.d/*.cnf
12 | # /etc/mysql/mysql.conf.d/*.cnf
13 | COPY ./scripts/my.cnf /etc/mysql/mysql.conf.d/
--------------------------------------------------------------------------------
/docker/mysql/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cd `dirname "$0"`
4 |
5 | echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
6 | echo ">>> Build MySQL image, all schemas required by this demo application will be initialized."
7 | docker build -t mydemo/mysql:5.7.18 .
8 | echo "<<< Finished: mydemo/mysql:5.7.18"
--------------------------------------------------------------------------------
/docker/mysql/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | docker run -d --net=mydemo --name mysql -p 13306:3306 -e MYSQL_ROOT_PASSWORD=123 mydemo/mysql:5.7.18
--------------------------------------------------------------------------------
/docker/mysql/scripts/5-skywalking.sql:
--------------------------------------------------------------------------------
1 | DROP DATABASE IF EXISTS `skywalking`;
2 | CREATE SCHEMA `skywalking` DEFAULT CHARACTER SET utf8 ;
--------------------------------------------------------------------------------
/docker/mysql/scripts/9-users.sql:
--------------------------------------------------------------------------------
1 | CREATE USER mydemo IDENTIFIED BY 'mydemo';
2 | GRANT ALL ON `mydemo-dn0`.* TO mydemo@'%';
3 | GRANT ALL ON `mydemo-dn1`.* TO mydemo@'%';
4 | GRANT ALL ON `mydemo-dn2`.* TO mydemo@'%';
5 | GRANT ALL ON `mydemo-dn3`.* TO mydemo@'%';
6 | GRANT ALL ON `mydemo-dn4`.* TO mydemo@'%';
7 |
8 | CREATE USER nacos IDENTIFIED BY 'nacos';
9 | GRANT ALL ON `nacos`.* TO nacos@'%';
10 |
11 | CREATE USER zipkin IDENTIFIED BY 'zipkin';
12 | GRANT ALL ON `zipkin`.* TO zipkin@'%';
13 |
14 | CREATE USER skywalking IDENTIFIED BY 'skywalking';
15 | GRANT ALL ON `skywalking`.* TO skywalking@'%';
16 |
17 | CREATE USER seata IDENTIFIED BY 'seata';
18 | GRANT ALL ON `seata`.* TO seata@'%';
19 |
20 | GRANT ALL ON *.* TO root@'%';
21 |
22 | FLUSH PRIVILEGES;
--------------------------------------------------------------------------------
/docker/mysql/scripts/my.cnf:
--------------------------------------------------------------------------------
1 | [mysqld]
2 | max_connections=100
3 | default-storage-engine=INNODB
4 | max_allowed_packet=1M
5 | lower_case_table_names=1
--------------------------------------------------------------------------------
/docker/nacos/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mydemo/openjdk:8-jre-alpine
2 |
3 | # Official download: https://github.com/alibaba/nacos/releases
4 | # Download from github-mirror.bugkiller.org instead of github.com to improve speed, to resolve network issues in Chine.
5 | # ATTENTION: Security risks not clear!
6 | RUN curl -fL -o /home/nacos.tar.gz https://github.com/alibaba/nacos/releases/download/1.1.4/nacos-server-1.1.4.tar.gz \
7 | && tar xzf /home/nacos.tar.gz -C /home/ \
8 | && rm -rf /home/nacos.tar.gz
9 | WORKDIR /home/nacos
10 | ADD ./scripts/ ./
11 | # sh files with Windows format can't run in container (Alpine Linux), transform to unix format
12 | RUN dos2unix ./init.sh && dos2unix ./bin/startup.sh && ./init.sh
13 |
14 | ENV MYSQL_HOST=mysql MYSQL_PORT=3306 MYSQL_DB=nacos MYSQL_USER=nacos MYSQL_PSW=nacos
15 | EXPOSE 8848
16 | ENTRYPOINT ["bash", "bin/startup.sh", "-m", "standalone"]
17 |
--------------------------------------------------------------------------------
/docker/nacos/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cd `dirname "$0"`
4 |
5 | echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
6 | echo ">>> Build Nacos image"
7 | echo ">>> Official download: https://github.com/alibaba/nacos/releases"
8 | echo ">>> Download from github-mirror.bugkiller.org instead of github.com to improve speed."
9 | echo ">>> ATTENTION: Security risks not clear!"
10 | docker build -t mydemo/nacos:1.1.4 .
11 | echo "<<< Finished: mydemo/nacos:1.1.4"
--------------------------------------------------------------------------------
/docker/nacos/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | docker run -d --net=mydemo --name nacos -p 18848:8848 -e MYSQL_HOST=mysql mydemo/nacos:1.1.4
--------------------------------------------------------------------------------
/docker/nacos/scripts/init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cd `dirname "$0"`
4 |
5 | # Change startup process from daemon to foreground mode
6 | sed -i '/echo "$JAVA ${JAVA_OPT}"/'d bin/startup.sh
7 | sed -i 's/nohup.*/$JAVA ${JAVA_OPT} nacos.nacos/g' bin/startup.sh
8 | sed -i '/echo "nacos is starting,you can check the/'d bin/startup.sh
9 | # Decrease memory allocation
10 | sed -i 's/-Xms512m -Xmx512m -Xmn256m/-Xms128m -Xmx512m -Xmn32m/g' bin/startup.sh
11 | # Set MySQL configurations, and load configuration value from environment variables
12 | cp conf/application.properties.example conf/application.properties
13 | sed -i 's/db.num=2/db.num=1/g' conf/application.properties
14 | sed -i 's/db.url.0=jdbc:mysql:\/\/11.162.196.16:3306\/nacos_devtest/db.url.0=jdbc:mysql:\/\/${MYSQL_HOST:127.0.0.1}:${MYSQL_PORT:3306}\/${MYSQL_DB:nacos}/g' conf/application.properties
15 | sed -i '/db.url.1/'d conf/application.properties
16 | sed -i 's/db.user=nacos_devtest/db.user=${MYSQL_USER:nacos}/g' conf/application.properties
17 | sed -i 's/db.password=nacos/db.password=${MYSQL_PSW:nacos}/g' conf/application.properties
--------------------------------------------------------------------------------
/docker/seata/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mydemo/openjdk:8-jre-alpine
2 |
3 | # Official download: https://github.com/seata/seata/releases
4 | # Download from github-mirror.bugkiller.org instead of github.com to improve speed.
5 | # ATTENTION: Security risks not clear!
6 | RUN curl -fL -o /home/seata.tar.gz http://github-mirror.bugkiller.org/seata/seata/releases/download/v1.0.0/seata-server-1.0.0.tar.gz \
7 | && tar xzf /home/seata.tar.gz -C /home/ \
8 | && rm -rf /home/seata.tar.gz
9 | WORKDIR /home/seata
10 | ADD ./scripts/ ./
11 | # sh files with Windows format can't run in container (Alpine Linux), transform to unix format
12 | RUN dos2unix bin/seata-server.sh \
13 | && dos2unix conf/init.sh \
14 | && dos2unix conf/nacos-config.sh
15 |
16 | ENV NACOS_HOST=nacos NACOS_PORT=8848 MYSQL_HOST=mysql MYSQL_PORT=3306 MYSQL_DB=seata MYSQL_USER=seata MYSQL_PSW=seata SEATA_HOST=seata SEATA_PORT=8091
17 | EXPOSE 8091
18 | ENTRYPOINT ["bin/seata-server.sh", "-h", "127.0.0.1", "-p", "$SEATA_PORT", "-m", "db", "-n", "1", "-e", "test"]
--------------------------------------------------------------------------------
/docker/seata/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cd `dirname "$0"`
4 |
5 | echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
6 | echo ">>> Build Seata image"
7 | echo ">>> Official download: https://github.com/seata/seata/releases"
8 | echo ">>> Download from github-mirror.bugkiller.org instead of github.com to improve speed."
9 | echo ">>> ATTENTION: Security risks not clear!"
10 | docker build -t mydemo/seata:1.0.0 .
11 | echo "<<< Finished: mydemo/seata:1.0.0"
--------------------------------------------------------------------------------
/docker/seata/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | docker run -d --net=mydemo --name seata -e NACOS_HOST=nacos -e NACOS_PORT=8848 -e MYSQL_HOST=mysql -e MYSQL_PORT=3306 -e MYSQL_USER=seata -e MYSQL_PSW=seata -e SEATA_HOST=seata -e SEATA_PORT=8091 mydemo/seata:1.0.0
--------------------------------------------------------------------------------
/docker/seata/scripts/conf/config.txt:
--------------------------------------------------------------------------------
1 | transport.type=TCP
2 | transport.server=NIO
3 | transport.heartbeat=true
4 | transport.enable-client-batch-send-request=false
5 | transport.thread-factory.boss-thread-prefix=NettyBoss
6 | transport.thread-factory.worker-thread-prefix=NettyServerNIOWorker
7 | transport.thread-factory.server-executor-thread-prefix=NettyServerBizHandler
8 | transport.thread-factory.share-boss-worker=false
9 | transport.thread-factory.client-selector-thread-prefix=NettyClientSelector
10 | transport.thread-factory.client-selector-thread-size=1
11 | transport.thread-factory.client-worker-thread-prefix=NettyClientWorkerThread
12 | transport.thread-factory.boss-thread-size=1
13 | transport.thread-factory.worker-thread-size=8
14 | transport.shutdown.wait=3
15 | service.vgroup_mapping.my_demo_gtx=default
16 | service.default.grouplist=seata:8091
17 | service.enableDegrade=false
18 | service.disableGlobalTransaction=false
19 | client.rm.async.commit.buffer.limit=10000
20 | client.rm.lock.retry.internal=10
21 | client.rm.lock.retry.times=30
22 | client.rm.report.retry.count=5
23 | client.rm.lock.retry.policy.branch-rollback-on-conflict=true
24 | client.rm.table.meta.check.enable=false
25 | client.rm.report.success.enable=true
26 | client.tm.commit.retry.count=5
27 | client.tm.rollback.retry.count=5
28 | store.mode=db
29 | store.db.datasource=dbcp
30 | store.db.db-type=mysql
31 | store.db.driver-class-name=com.mysql.jdbc.Driver
32 | store.db.url=jdbc:mysql://mysql:3306/seata?useUnicode=true
33 | store.db.user=seata
34 | store.db.password=seata
35 | store.db.min-conn=1
36 | store.db.max-conn=5
37 | store.db.global.table=global_table
38 | store.db.branch.table=branch_table
39 | store.db.query-limit=100
40 | store.db.lock-table=lock_table
41 | server.recovery.committing-retry-period=1000
42 | server.recovery.asyn-committing-retry-period=1000
43 | server.recovery.rollbacking-retry-period=1000
44 | server.recovery.timeout-retry-period=1000
45 | server.max.commit.retry.timeout=-1
46 | server.max.rollback.retry.timeout=-1
47 | server.rollback.retry.timeout.unlock.enable=false
48 | client.undo.data.validation=true
49 | client.undo.log.serialization=jackson
50 | server.undo.log.save.days=7
51 | server.undo.log.delete.period=86400000
52 | client.undo.log.table=undo_log
53 | client.log.exceptionRate=100
54 | transport.serialization=seata
55 | transport.compressor=none
56 | metrics.enabled=false
--------------------------------------------------------------------------------
/docker/seata/scripts/conf/init.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | cd $(dirname "$0")
4 |
5 | echo ">>> To check Nacos status"
6 | # nc, nmap, telnet not installed in this image, use curl instead
7 | VALUE=$(curl -s --connect-timeout 1 -X GET "http://$NACOS_HOST:$NACOS_PORT/nacos/v1/cs/configs?dataId=service.vgroup_mapping.my_demo_gtx&group=SEATA_GROUP")
8 | if [ $? -ne 0 ]; then
9 | echo " Error: Nacos not started properly!"
10 | exit 1
11 | fi
12 | if [[ "$VALUE" != "" && "$VALUE" != "default" && "$VALUE" != "config data not exist" ]]; then
13 | echo " Error: Get config from Nacos returned error message: $VALUE"
14 | exit 1
15 | fi
16 | echo " Nacos is running on $NACOS_HOST:$NACOS_PORT"
17 |
18 | # Config Seata
19 | sed -i "s/serverAddr.*/serverAddr=\"$NACOS_HOST:$NACOS_PORT\"/g" registry.conf
20 | echo "Config: store.db.user=$MYSQL_USER"
21 | sed -i "s/store.db.user.*/store.db.user=$MYSQL_USER/g" config.txt
22 | sed -i "s/store.db.password.*/store.db.password=$MYSQL_PSW/g" config.txt
23 | echo "Config: store.db.url=jdbc:mysql://$MYSQL_HOST:$MYSQL_PORT/$MYSQL_DB?useUnicode=true"
24 | sed -i "s/store.db.url.*/store.db.url=jdbc:mysql:\/\/$MYSQL_HOST:$MYSQL_PORT\/$MYSQL_DB?useUnicode=true/g" config.txt
25 | echo "Config: service.default.grouplist=$SEATA_HOST:$SEATA_PORT"
26 | sed -i "s/service.default.grouplist.*/service.default.grouplist=$SEATA_HOST:$SEATA_PORT/g" config.txt
27 |
28 | echo ">>> To import Seata configs into Nacos"
29 | ./nacos-config.sh -h $NACOS_HOST -p $NACOS_PORT
30 |
--------------------------------------------------------------------------------
/docker/seata/scripts/conf/nacos-config.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Copyright 1999-2019 Seata.io Group.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at、
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | DIR=`dirname "$0"`
17 | cd $DIR
18 |
19 | while getopts ":h:p:g:t:" opt
20 | do
21 | case $opt in
22 | h)
23 | host=$OPTARG
24 | ;;
25 | p)
26 | port=$OPTARG
27 | ;;
28 | g)
29 | group=$OPTARG
30 | ;;
31 | t)
32 | tenant=$OPTARG
33 | ;;
34 | ?)
35 | echo "USAGE OPTION: $0 [-h host] [-p port] [-g group] [-t tenant] "
36 | exit 1
37 | ;;
38 | esac
39 | done
40 |
41 | if [[ -z ${host} ]]; then
42 | host=localhost
43 | fi
44 | if [[ -z ${port} ]]; then
45 | port=8848
46 | fi
47 | if [[ -z ${group} ]]; then
48 | group="SEATA_GROUP"
49 | fi
50 | if [[ -z ${tenant} ]]; then
51 | tenant=""
52 | fi
53 |
54 | nacosAddr=$host:$port
55 | contentType="content-type:application/json;charset=UTF-8"
56 |
57 | echo " set nacosAddr=$nacosAddr"
58 | echo " set group=$group"
59 |
60 | failCount=0
61 | tempLog=$(mktemp -u)
62 |
63 | function addConfig() {
64 | curl -X POST -H "${1}" "http://$2/nacos/v1/cs/configs?dataId=$3&group=$group&content=$4&tenant=$tenant" > "${tempLog}" 2>/dev/null
65 | if [[ -z $(cat "${tempLog}") ]]; then
66 | echo " Please check the cluster status."
67 | exit 1
68 | fi
69 | if [[ $(cat "${tempLog}") =~ "true" ]]; then
70 | echo " Set $3=$4 successfully "
71 | else
72 | echo " Set $3=$4 failure "
73 | (( failCount++ ))
74 | fi
75 | }
76 |
77 | count=0
78 | for line in $(cat ./config.txt); do
79 | (( count++ ))
80 | key=${line%%=*}
81 | value=${line#*=}
82 | addConfig "${contentType}" "${nacosAddr}" "${key}" "${value}"
83 | done
84 |
85 | echo " ========================================================================="
86 | echo " Complete initialization parameters, \033[32m total-count:$count \033[0m, \033[31m failure-count:$failCount \033[0m"
87 | echo " ========================================================================="
88 |
89 | if [[ ${failCount} -eq 0 ]]; then
90 | echo " \033[32m Init nacos config finished, please start seata-server. \033[0m"
91 | else
92 | echo " \033[31m init nacos config fail. \033[0m"
93 | fi
94 |
--------------------------------------------------------------------------------
/docker/seata/scripts/conf/registry.conf:
--------------------------------------------------------------------------------
1 | registry {
2 | type = "nacos" # file、nacos、eureka、redis、zk、consul、etcd3、sofa
3 | nacos {
4 | serverAddr = "nacos:8848"
5 | namespace = ""
6 | cluster = "default"
7 | }
8 | }
9 | config {
10 | type = "nacos" # file、nacos、apollo、zk、consul、etcd3
11 | nacos {
12 | serverAddr = "nacos:8848"
13 | namespace = ""
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/docker/shardingproxy/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mydemo/openjdk:8-jre-alpine
2 |
3 | # Download ShardingProxy
4 | RUN curl -fL -o /home/shardingproxy.tar.gz http://mirrors.tuna.tsinghua.edu.cn/apache/incubator/shardingsphere/4.0.0-RC3/apache-shardingsphere-incubating-4.0.0-RC3-sharding-proxy-bin.tar.gz \
5 | && tar xzf /home/shardingproxy.tar.gz -C /home/ \
6 | && rm -rf /home/shardingproxy.tar.gz \
7 | && mv /home/apache-shardingsphere-incubating-4.0.0-RC3-sharding-proxy-bin /home/shardingproxy \
8 | && curl -fL -o /home/shardingproxy/lib/mysql-connector-java-5.1.47.jar http://maven.aliyun.com/nexus/content/groups/public/mysql/mysql-connector-java/5.1.47/mysql-connector-java-5.1.47.jar
9 | WORKDIR /home/shardingproxy
10 | ADD ./scripts/ ./
11 | # sh files with Windows format can't run in container (Alpine Linux), transform to unix format
12 | RUN dos2unix bin/docker-entrypoint.sh
13 |
14 | ENV MYSQL_HOST=mysql MYSQL_PORT=3306 MYSQL_USER=mydemo MYSQL_PSW=mydemo
15 | EXPOSE 3307
16 | ENTRYPOINT ["bin/docker-entrypoint.sh"]
--------------------------------------------------------------------------------
/docker/shardingproxy/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd `dirname "$0"`
4 |
5 | echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
6 | echo ">>> Build ShardingProxy image"
7 | docker build -t mydemo/shardingproxy:4.0.0-RC3 .
8 | echo "<<< Finished: mydemo/shardingproxy:4.0.0-RC3"
--------------------------------------------------------------------------------
/docker/shardingproxy/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | docker run -d --net=mydemo --name shardingproxy -p 13307:3307 -e MYSQL_HOST=mysql mydemo/shardingproxy:4.0.0-RC3
--------------------------------------------------------------------------------
/docker/shardingproxy/scripts/bin/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SHARDINGPROXY_HOME=`dirname "$0"`
4 | cd $SHARDINGPROXY_HOME/..
5 | SHARDINGPROXY_HOME=`pwd`
6 |
7 | if [[ -z "$MYSQL_HOST" || -z "$MYSQL_PORT" || -z "$MYSQL_USER" || -z "$MYSQL_PSW" ]]; then
8 | echo "ENV: MYSQL_HOST, MYSQL_PORT, MYSQL_USER or MYSQL_PSW is empty"
9 | exit 1
10 | fi
11 | sed -i "s/jdbc:mysql:\/\/[^\/]*/jdbc:mysql:\/\/$MYSQL_HOST:$MYSQL_PORT/g" $SHARDINGPROXY_HOME/conf/config-order.yaml
12 | sed -i "s/username:.*/username: $MYSQL_USER/g" $SHARDINGPROXY_HOME/conf/config-order.yaml
13 | sed -i "s/password:.*/password: $MYSQL_PSW/g" $SHARDINGPROXY_HOME/conf/config-order.yaml
14 | sed -i "s/jdbc:mysql:\/\/[^\/]*/jdbc:mysql:\/\/$MYSQL_HOST:$MYSQL_PORT/g" $SHARDINGPROXY_HOME/conf/config-user.yaml
15 | sed -i "s/username:.*/username: $MYSQL_USER/g" $SHARDINGPROXY_HOME/conf/config-user.yaml
16 | sed -i "s/password:.*/password: $MYSQL_PSW/g" $SHARDINGPROXY_HOME/conf/config-user.yaml
17 |
18 | # 启动ShardingProxy
19 | CLASS_PATH=.:${SHARDINGPROXY_HOME}/conf:${SHARDINGPROXY_HOME}/lib/*
20 | JAVA_OPTS=" -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true "
21 | JAVA_MEM_OPTS=""
22 | MAIN_CLASS=org.apache.shardingsphere.shardingproxy.Bootstrap
23 | if [ $# == 1 ]; then
24 | MAIN_CLASS=${MAIN_CLASS}" "$1
25 | echo "The port is configured as $1"
26 | fi
27 | if [ $# == 2 ]; then
28 | MAIN_CLASS=${MAIN_CLASS}" "$1" "$2
29 | echo "The port is configured as $1"
30 | echo "The configuration file is $SHARDINGPROXY_HOME/conf/$2"
31 | fi
32 | java ${JAVA_OPTS} ${JAVA_MEM_OPTS} -classpath ${CLASS_PATH} ${MAIN_CLASS}
--------------------------------------------------------------------------------
/docker/shardingproxy/scripts/conf/config-order.yaml:
--------------------------------------------------------------------------------
1 | schemaName: db_order
2 | dataSources:
3 | ds_0:
4 | url: jdbc:mysql://127.0.0.1:3306/mydemo-dn1?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
5 | username: root
6 | password: 1234
7 | connectionTimeoutMilliseconds: 3000
8 | idleTimeoutMilliseconds: 60000
9 | maxLifetimeMilliseconds: 1800000
10 | maxPoolSize: 3
11 | ds_1:
12 | url: jdbc:mysql://127.0.0.1:3306/mydemo-dn2?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
13 | username: root
14 | password: 1234
15 | connectionTimeoutMilliseconds: 3000
16 | idleTimeoutMilliseconds: 60000
17 | maxLifetimeMilliseconds: 1800000
18 | maxPoolSize: 3
19 | ds_2:
20 | url: jdbc:mysql://127.0.0.1:3306/mydemo-dn3?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
21 | username: root
22 | password: 1234
23 | connectionTimeoutMilliseconds: 3000
24 | idleTimeoutMilliseconds: 60000
25 | maxLifetimeMilliseconds: 1800000
26 | maxPoolSize: 3
27 | ds_3:
28 | url: jdbc:mysql://127.0.0.1:3306/mydemo-dn4?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
29 | username: root
30 | password: 1234
31 | connectionTimeoutMilliseconds: 3000
32 | idleTimeoutMilliseconds: 60000
33 | maxLifetimeMilliseconds: 1800000
34 | maxPoolSize: 3
35 | shardingRule:
36 | tables:
37 | ord_order:
38 | actualDataNodes: ds_${0..3}.ord_order
39 | databaseStrategy:
40 | inline:
41 | shardingColumn: order_id
42 | algorithmExpression: ds_${order_id % 4}
43 | ord_order_item:
44 | actualDataNodes: ds_${0..3}.ord_order_item
45 | databaseStrategy:
46 | inline:
47 | shardingColumn: order_id
48 | algorithmExpression: ds_${order_id % 4}
49 | keyGenerator:
50 | type: SNOWFLAKE
51 | column: order_item_id
52 | props:
53 | worker.id: 1
54 | max.tolerate.time.difference.milliseconds: 600000
55 | ord_user_order:
56 | actualDataNodes: ds_${0..3}.ord_user_order
57 | databaseStrategy:
58 | inline:
59 | shardingColumn: user_id
60 | algorithmExpression: ds_${user_id % 17 % 4}
61 | undo_log:
62 | actualDataNodes: ds_0.undo_log
63 | bindingTables:
64 | - ord_order,ord_order_item
65 | defaultDataSourceName: ds_0
66 | defaultDatabaseStrategy:
67 | none:
68 | defaultTableStrategy:
69 | none:
--------------------------------------------------------------------------------
/docker/shardingproxy/scripts/conf/config-user.yaml:
--------------------------------------------------------------------------------
1 | schemaName: db_user
2 | dataSources:
3 | ds_0:
4 | url: jdbc:mysql://127.0.0.1:3306/mydemo-dn1?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
5 | username: root
6 | password: 1234
7 | connectionTimeoutMilliseconds: 3000
8 | idleTimeoutMilliseconds: 60000
9 | maxLifetimeMilliseconds: 1800000
10 | maxPoolSize: 3
11 | ds_1:
12 | url: jdbc:mysql://127.0.0.1:3306/mydemo-dn2?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
13 | username: root
14 | password: 1234
15 | connectionTimeoutMilliseconds: 3000
16 | idleTimeoutMilliseconds: 60000
17 | maxLifetimeMilliseconds: 1800000
18 | maxPoolSize: 3
19 | shardingRule:
20 | tables:
21 | usr_user:
22 | actualDataNodes: ds_${0..1}.usr_user
23 | databaseStrategy:
24 | inline:
25 | shardingColumn: user_id
26 | algorithmExpression: ds_${user_id % 2}
27 | keyGenerator:
28 | type: SNOWFLAKE
29 | column: user_id
30 | props:
31 | worker.id: 1
32 | max.tolerate.time.difference.milliseconds: 600000
33 | usr_user_account:
34 | actualDataNodes: ds_${0..1}.usr_user_account
35 | databaseStrategy:
36 | inline:
37 | shardingColumn: account_hash
38 | algorithmExpression: ds_${account_hash % 2}
39 | undo_log:
40 | actualDataNodes: ds_0.undo_log
41 | defaultDataSourceName: ds_0
42 | defaultDatabaseStrategy:
43 | none:
44 | defaultTableStrategy:
45 | none:
--------------------------------------------------------------------------------
/docker/shardingproxy/scripts/conf/server.yaml:
--------------------------------------------------------------------------------
1 | #orchestration:
2 | # name: orchestration_ds
3 | # overwrite: true
4 | # registry:
5 | # type: zookeeper
6 | # serverLists: 192.168.31.108:2181
7 | # namespace: orchestration
8 | authentication:
9 | users: # Account for connecting to ShardingProxy
10 | root: # root user without authorizedSchemas specified can access all logical schemas
11 | password: 123
12 | mydemo: # mydemo user
13 | password: mydemo
14 | authorizedSchemas: db_user, db_order
15 | props:
16 | acceptor.size: 4 # Number of workers for client connections
17 | proxy.transaction.type: LOCAL
18 | sql.show: true
19 |
--------------------------------------------------------------------------------
/docker/skywalking/README.md:
--------------------------------------------------------------------------------
1 | Build 4 SkyWalking images:
2 | 1. `skywalking-base`: A full SkyWalking distribution package, including OAP service, webapp (UI) and agent.
3 | It's the base image for other 3 SkyWalking images using [multi-stage builds](https://docs.docker.com/develop/develop-images/multistage-build/).
4 | 2. `skywalking-oap`: SkyWalking OAP service. The webapp and agent were removed.
5 | 3. `skywalking-ui`: SkyWalking webapp (UI). OAP service and agent were removed.
6 | 4. `skywalking-client`: A parent image for SkyWalking clients, with agent reserved, OAP service and webapp were removed.
--------------------------------------------------------------------------------
/docker/skywalking/base/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mydemo/openjdk:8-jre-alpine AS build
2 |
3 | WORKDIR /home
4 | # Download SkyWalking
5 | RUN curl -fL -o ./skywalking.tar.gz http://mirror.bit.edu.cn/apache/skywalking/6.6.0/apache-skywalking-apm-6.6.0.tar.gz \
6 | && tar xzf skywalking.tar.gz -C ./ \
7 | && rm -rf skywalking.tar.gz \
8 | && mv apache-skywalking-apm-bin skywalking \
9 | && curl -fL -o ./skywalking/oap-libs/mysql-connector-java-8.0.18.jar http://maven.aliyun.com/nexus/content/groups/public/mysql/mysql-connector-java/8.0.18/mysql-connector-java-8.0.18.jar \
10 | && rm -rf ./skywalking/bin
11 | ADD ./configs/ /home/skywalking/
12 | # sh files with Windows format can't run in container (Alpine Linux), transform to unix format
13 | RUN dos2unix /home/skywalking/oap.sh && dos2unix /home/skywalking/ui.sh
--------------------------------------------------------------------------------
/docker/skywalking/base/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd `dirname "$0"`
4 | docker build -t mydemo/skywalking-base:6.6.0 .
--------------------------------------------------------------------------------
/docker/skywalking/base/configs/config/application.yml:
--------------------------------------------------------------------------------
1 | cluster:
2 | standalone:
3 | core:
4 | default:
5 | role: ${SW_CORE_ROLE:Mixed} # Mixed/Receiver/Aggregator
6 | restHost: ${SW_CORE_REST_HOST:0.0.0.0}
7 | restPort: ${SW_CORE_REST_PORT:12800}
8 | restContextPath: ${SW_CORE_REST_CONTEXT_PATH:/}
9 | gRPCHost: ${SW_CORE_GRPC_HOST:0.0.0.0}
10 | gRPCPort: ${SW_CORE_GRPC_PORT:11800}
11 | downsampling:
12 | - Hour
13 | - Day
14 | - Month
15 | enableDataKeeperExecutor: ${SW_CORE_ENABLE_DATA_KEEPER_EXECUTOR:true} # Turn it off then automatically metrics data delete will be close.
16 | dataKeeperExecutePeriod: ${SW_CORE_DATA_KEEPER_EXECUTE_PERIOD:5} # How often the data keeper executor runs periodically, unit is minute
17 | recordDataTTL: ${SW_CORE_RECORD_DATA_TTL:90} # Unit is minute
18 | minuteMetricsDataTTL: ${SW_CORE_MINUTE_METRIC_DATA_TTL:90} # Unit is minute
19 | hourMetricsDataTTL: ${SW_CORE_HOUR_METRIC_DATA_TTL:36} # Unit is hour
20 | dayMetricsDataTTL: ${SW_CORE_DAY_METRIC_DATA_TTL:45} # Unit is day
21 | monthMetricsDataTTL: ${SW_CORE_MONTH_METRIC_DATA_TTL:18} # Unit is month
22 | enableDatabaseSession: ${SW_CORE_ENABLE_DATABASE_SESSION:true}
23 | storage:
24 | mysql:
25 | properties:
26 | jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://mysql:3306/skywalking"}
27 | dataSource.user: ${SW_DATA_SOURCE_USER:skywalking}
28 | dataSource.password: ${SW_DATA_SOURCE_PASSWORD:skywalking}
29 | dataSource.cachePrepStmts: ${SW_DATA_SOURCE_CACHE_PREP_STMTS:true}
30 | dataSource.prepStmtCacheSize: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_SIZE:250}
31 | dataSource.prepStmtCacheSqlLimit: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_LIMIT:2048}
32 | dataSource.useServerPrepStmts: ${SW_DATA_SOURCE_USE_SERVER_PREP_STMTS:true}
33 | dataSource.useSSL: false # 添加的
34 | metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:5000}
35 | receiver-sharing-server:
36 | default:
37 | receiver-register:
38 | default:
39 | receiver-trace:
40 | default:
41 | bufferPath: ${SW_RECEIVER_BUFFER_PATH:/home/skywalking/trace-buffer/} # Path to trace buffer files, suggest to use absolute path
42 | bufferOffsetMaxFileSize: ${SW_RECEIVER_BUFFER_OFFSET_MAX_FILE_SIZE:100} # Unit is MB
43 | bufferDataMaxFileSize: ${SW_RECEIVER_BUFFER_DATA_MAX_FILE_SIZE:500} # Unit is MB
44 | bufferFileCleanWhenRestart: ${SW_RECEIVER_BUFFER_FILE_CLEAN_WHEN_RESTART:false}
45 | sampleRate: ${SW_TRACE_SAMPLE_RATE:10000} # The sample rate precision is 1/10000. 10000 means 100% sample in default.
46 | slowDBAccessThreshold: ${SW_SLOW_DB_THRESHOLD:default:200,mongodb:100} # The slow database access thresholds. Unit ms.
47 | receiver-jvm:
48 | default:
49 | receiver-clr:
50 | default:
51 | service-mesh:
52 | default:
53 | bufferPath: ${SW_SERVICE_MESH_BUFFER_PATH:/home/skywalking/mesh-buffer/} # Path to trace buffer files, suggest to use absolute path
54 | bufferOffsetMaxFileSize: ${SW_SERVICE_MESH_OFFSET_MAX_FILE_SIZE:100} # Unit is MB
55 | bufferDataMaxFileSize: ${SW_SERVICE_MESH_BUFFER_DATA_MAX_FILE_SIZE:500} # Unit is MB
56 | bufferFileCleanWhenRestart: ${SW_SERVICE_MESH_BUFFER_FILE_CLEAN_WHEN_RESTART:false}
57 | istio-telemetry:
58 | default:
59 | envoy-metric:
60 | default:
61 | query:
62 | graphql:
63 | path: ${SW_QUERY_GRAPHQL_PATH:/graphql}
64 | alarm:
65 | default:
66 | telemetry:
67 | none:
68 | configuration:
69 | none:
--------------------------------------------------------------------------------
/docker/skywalking/base/configs/config/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
22 | ${sys:oap.logDir}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/docker/skywalking/base/configs/oap.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | CLASSPATH="config:$CLASSPATH"
4 | for i in oap-libs/*.jar
5 | do
6 | CLASSPATH="$i:$CLASSPATH"
7 | done
8 |
9 | echo "Location: `pwd`"
10 | SW_JDBC_URL=jdbc:mysql://$MYSQL_HOST:$MYSQL_PORT/$MYSQL_DB
11 | SW_DATA_SOURCE_USER=$MYSQL_USER
12 | SW_DATA_SOURCE_PASSWOR=$MYSQL_PSW
13 | echo "SW_JDBC_URL: $SW_JDBC_URL"
14 | echo "SW_DATA_SOURCE_USER: $SW_DATA_SOURCE_USER"
15 |
16 | java ${JAVA_OPTS} -classpath ${CLASSPATH} org.apache.skywalking.oap.server.starter.OAPServerStartUp "$@"
--------------------------------------------------------------------------------
/docker/skywalking/base/configs/ui.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | pwd
4 | echo "java ${JAVA_OPTS} -jar webapp/skywalking-webapp.jar --spring.config.location=webapp/webapp.yml"
5 | java ${JAVA_OPTS} -jar webapp/skywalking-webapp.jar --spring.config.location=webapp/webapp.yml "$@"
--------------------------------------------------------------------------------
/docker/skywalking/base/configs/webapp/webapp.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | server:
18 | port: 8080
19 |
20 | collector:
21 | path: /graphql
22 | ribbon:
23 | ReadTimeout: 10000
24 | # Point to all backend's restHost:restPort, split by ,
25 | listOfServers: ${SKYWALKING_HOST:127.0.0.1}:${SKYWALKING_PORT:12800}
26 |
27 |
--------------------------------------------------------------------------------
/docker/skywalking/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd `dirname "$0"`
4 |
5 | echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
6 | echo ">>> Build SkyWalking images:"
7 | echo ">>> 1. skywalking-base: A full SkyWalking distribution package, including OAP service,"
8 | echo ">>> webapp (UI) and agent, ONLY \"AS build\"."
9 | echo ">>> 2. skywalking-oap: OAP service. The webapp and agent were removed."
10 | echo ">>> 3. skywalking-ui: The webapp. OAP service and agent were removed."
11 | echo ">>> 4. skywalking-client: A parent image for SkyWalking clients, with agent reserved,"
12 | echo ">>> OAP service and webapp were removed."
13 | ./base/build.sh
14 | echo "<<< Finished: mydemo/skywalking-base:6.6.0"
15 | ./oap/build.sh
16 | echo "<<< Finished: mydemo/skywalking-oap:6.6.0"
17 | ./ui/build.sh
18 | echo "<<< Finished: mydemo/skywalking-ui:6.6.0"
19 | ./client/build.sh
20 | echo "<<< Finished: mydemo/skywalking-client:6.6.0"
21 |
--------------------------------------------------------------------------------
/docker/skywalking/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mydemo/skywalking-base:6.6.0 AS build
2 |
3 | WORKDIR /home/skywalking
4 | RUN rm -rf oap-libs webapp
5 |
6 | FROM mydemo/openjdk:8-jre-alpine
7 |
8 | COPY --from=build /home/skywalking /home/skywalking
9 | ENV SKYWALKING_HOST=skywalking SKYWALKING_PORT=12800
--------------------------------------------------------------------------------
/docker/skywalking/client/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd `dirname "$0"`
4 | docker build -t mydemo/skywalking-client:6.6.0 .
--------------------------------------------------------------------------------
/docker/skywalking/oap/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mydemo/skywalking-base:6.6.0 AS build
2 |
3 | WORKDIR /home/skywalking
4 | RUN rm -rf agent webapp
5 |
6 | FROM mydemo/openjdk:8-jre-alpine
7 |
8 | COPY --from=build /home/skywalking /home/skywalking
9 | WORKDIR /home/skywalking
10 | ENV MYSQL_HOST=mysql MYSQL_PORT=3306 MYSQL_USER=skywalking MYSQL_PSW=skywalking MYSQL_DB=skywalking
11 | EXPOSE 12800 11800
12 | ENTRYPOINT ["./oap.sh"]
--------------------------------------------------------------------------------
/docker/skywalking/oap/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd `dirname "$0"`
4 | docker build --rm -t mydemo/skywalking-oap:6.6.0 .
--------------------------------------------------------------------------------
/docker/skywalking/oap/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | docker run -d --net=mydemo --name skywalking-oap -e MYSQL_HOST=mysql -e MYSQL_PORT=3306 -e MYSQL_USER=skywalking -e MYSQL_PSW=skywalking -e MYSQL_DB=skywalking mydemo/skywalking-oap:6.6.0
--------------------------------------------------------------------------------
/docker/skywalking/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd `dirname "$0"`
4 | ./oap/run.sh
5 | ./ui/run.sh
--------------------------------------------------------------------------------
/docker/skywalking/ui/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mydemo/skywalking-base:6.6.0 AS build
2 |
3 | WORKDIR /home/skywalking
4 | RUN rm -rf agent oap-libs
5 |
6 | FROM mydemo/openjdk:8-jre-alpine
7 |
8 | COPY --from=build /home/skywalking /home/skywalking
9 | WORKDIR /home/skywalking
10 | ENV SKYWALKING_HOST=skywalking SKYWALKING_PORT=12800
11 | EXPOSE 8080
12 | ENTRYPOINT ["./ui.sh"]
--------------------------------------------------------------------------------
/docker/skywalking/ui/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd `dirname "$0"`
4 | docker build -t mydemo/skywalking-ui:6.6.0 .
--------------------------------------------------------------------------------
/docker/skywalking/ui/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | docker run -d --net=mydemo --name skywalking-ui -e SKYWALKING_HOST=skywalking-oap -p 18080:8080 mydemo/skywalking-ui:6.6.0
--------------------------------------------------------------------------------
/docker/zipkin/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mydemo/openjdk:8-jre-alpine
2 |
3 | WORKDIR /home
4 | ADD ./zipkin.jar /home/
5 |
6 | ENV STORAGE_TYPE=mysql MYSQL_HOST=mysql MYSQL_TCP_PORT=3306 MYSQL_DB=zipkin MYSQL_USER=zipkin MYSQL_PASS=zipkin
7 | EXPOSE 9411
8 | ENTRYPOINT ["java", "-jar", "/home/zipkin.jar"]
--------------------------------------------------------------------------------
/docker/zipkin/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd $(dirname "$0")
4 |
5 | echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
6 | echo ">>> Build ZipKin image"
7 | echo ">>> ZipKin's official download: curl -sSL https://zipkin.io/quickstart.sh | bash -s"
8 | echo ">>> I've made some changes:"
9 | echo ">>> 1. Download from maven.aliyun.com to improve speed."
10 | echo ">>> 2. Download 2.19.2 instead of the latest."
11 | ./quickstart.sh
12 |
13 | docker build -t mydemo/zipkin:2.19.2 .
14 | rm -rf zipkin*
15 | echo "<<< Finished: mydemo/zipkin:2.19.2"
--------------------------------------------------------------------------------
/docker/zipkin/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | docker run -d --net=mydemo --name zipkin -p 19411:9411 -e MYSQL_HOST=mysql mydemo/zipkin:2.19.2
--------------------------------------------------------------------------------
/docs/Dubbo-basis.md:
--------------------------------------------------------------------------------
1 | #### 基本用法
2 | 使用[apache/dubbo-spring-boot-project](https://github.com/apache/dubbo-spring-boot-project)与`SpringBoot`集成,注册中心使用`Nacos`。
3 |
4 | 1. `pom.xml`添加依赖项:
5 | ```xml
6 |
7 | org.apache.dubbo
8 | dubbo-spring-boot-starter
9 | 2.7.5
10 |
11 |
12 | org.apache.dubbo
13 | dubbo
14 | 2.7.5
15 |
16 | ```
17 | 2. 在`application.yml`中配置protocol、registry等:
18 | ```yaml
19 | dubbo:
20 | application:
21 | id: srv-item
22 | name: srv-item
23 | qosEnable: false
24 | protocol:
25 | id: dubbo
26 | name: dubbo
27 | port: 20880
28 | threads: 3
29 | iothreads: 1
30 | server: netty
31 | client: netty
32 | status: server
33 | queues: 0
34 | keepAlive: true
35 | registry:
36 | address: nacos://127.0.0.1:8848
37 | ```
38 | 最新配置项参考[ApplicationConfig](https://github.com/apache/dubbo/blob/master/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java)、[ProtocolConfig](https://github.com/apache/dubbo/blob/master/dubbo-common/src/main/java/org/apache/dubbo/config/ProtocolConfig.java)、[RegistryConfig](https://github.com/apache/dubbo/blob/master/dubbo-common/src/main/java/org/apache/dubbo/config/RegistryConfig.java)、[MonitorConfig](https://github.com/apache/dubbo/blob/master/dubbo-common/src/main/java/org/apache/dubbo/config/MonitorConfig.java)、[ServiceConfig](https://github.com/apache/dubbo/blob/master/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java)、[ReferenceConfig](https://github.com/apache/dubbo/blob/master/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java)
39 | 3. `SpringBoot`启动类上指定`Dubbo`组件扫描范围:
40 | ```java
41 | @Configuration
42 | @EnableAutoConfiguration
43 | @ComponentScan(basePackages={"my.demo.service.item"})
44 | @EnableDubbo(basePackages = { "my.demo.service.item" })
45 | public class Application {
46 | public static void main(String[] args) {
47 | new SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE).run(args);
48 | }
49 | }
50 | ```
51 | 4. 暴露`Dubbo`服务的类上使用`@Service`注解(不再需要Spring的`@Component`),引用`Dubbo`服务使用`@Reference`(不再需要Spring的`@Autowired`);
52 |
53 | #### 使用`native-thrift`协议
54 | 开源RPC协议中,`Thrift`是效率最好的,在`Dubbo`中可以使用`native-thrift`协议,但比较麻烦,有不少手工工作,还有一些限制,例如服务方法不能返回null等。
55 |
56 | 1. 以Windows环境为例,下载[thrift-0.12.0.exe](http://archive.apache.org/dist/thrift/0.12.0/thrift-0.12.0.exe)(这是`Dubbo`支持的`Thrift`版本)。
57 | 2. 为服务方法编写IDL文件,例如`HelloService.thrift`:
58 | ```idl
59 | namespace java thriftdemo.service
60 |
61 | service HelloService {
62 | string hello( 1:required string name );
63 | }
64 | ```
65 | IDL语法参考[Thrift interface description language](http://thrift.apache.org/docs/idl)、[Thrift Types](http://thrift.apache.org/docs/types)。
66 | 3. 使用`Thrift`生成Java类:`thrift-0.12.0.exe -gen java HelloService.thrift`,将Java类拷贝到相应package中。
67 | 4. `Dubbo`的provider、consumer都指定protocol name为`native-thrift`,如果直连,协议名称也使用`native-thrift://xxxx:xx`。
68 | 5. `Dubbo`的provider和consumer都使用`HelloService.Iface`接口。
--------------------------------------------------------------------------------
/docs/images/architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/architecture.png
--------------------------------------------------------------------------------
/docs/images/db-sharding-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/db-sharding-1.png
--------------------------------------------------------------------------------
/docs/images/db-sharding-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/db-sharding-2.png
--------------------------------------------------------------------------------
/docs/images/docker-containers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/docker-containers.png
--------------------------------------------------------------------------------
/docs/images/docker-download-curl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/docker-download-curl.png
--------------------------------------------------------------------------------
/docs/images/docker-download-wget.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/docker-download-wget.png
--------------------------------------------------------------------------------
/docs/images/docker-stats.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/docker-stats.png
--------------------------------------------------------------------------------
/docs/images/kubernetes-overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/kubernetes-overview.png
--------------------------------------------------------------------------------
/docs/images/mycat-explain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/mycat-explain.png
--------------------------------------------------------------------------------
/docs/images/newman-output.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/newman-output.jpg
--------------------------------------------------------------------------------
/docs/images/order-service-out.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/order-service-out.png
--------------------------------------------------------------------------------
/docs/images/postman.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/postman.jpg
--------------------------------------------------------------------------------
/docs/images/shopweb-out.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/shopweb-out.png
--------------------------------------------------------------------------------
/docs/images/table-schema.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/images/table-schema.png
--------------------------------------------------------------------------------
/docs/source.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/docs/source.pptx
--------------------------------------------------------------------------------
/fitnesse/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mydemo/openjdk:8-jre-alpine
2 |
3 | #RUN curl -fL -o /home/fitnesse-standalone.jar http://fitnesse.org/fitnesse-standalone.jar?responder=releaseDownload&release=20200308
4 | ADD fitnesse-standalone.jar /home/
5 | ADD target/lib/ /home/lib
6 | ADD target/fitnesse-0.0.1-SNAPSHOT.jar /home/lib/
7 |
8 | ENV NACOS_HOST=nacos MYSQL_HOST=mysql
9 | EXPOSE 8011
10 | ENTRYPOINT ["java", "-jar", "/home/fitnesse-standalone.jar", "-p", "8011", "-l", "/home/fitnesse.log"]
--------------------------------------------------------------------------------
/fitnesse/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd `dirname $0`
4 | mvn clean package -P dev
5 | docker stop fitnesse
6 | docker rm fitnesse
7 | docker rmi mydemo/fitnesse:latest
8 | docker build -t mydemo/fitnesse .
--------------------------------------------------------------------------------
/fitnesse/fitnesse-standalone.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuzhibin-cn/my-demo/966c526998e396acb6af3e76f08c68de0bcfca12/fitnesse/fitnesse-standalone.jar
--------------------------------------------------------------------------------
/fitnesse/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | my.demo
9 | mydemo-parent
10 | 0.0.1-SNAPSHOT
11 |
12 |
13 | fitnesse
14 |
15 |
16 | fitnesse
17 |
18 |
19 |
20 |
21 |
22 | src/main/resources
23 | true
24 |
25 | application.yml
26 | logback.xml
27 |
28 |
29 |
30 |
31 |
32 | org.apache.maven.plugins
33 | maven-dependency-plugin
34 | 3.1.2
35 |
36 |
37 | copy-dependencies
38 | package
39 |
40 | copy-dependencies
41 |
42 |
43 | ${project.build.directory}/lib
44 | false
45 | false
46 | true
47 | runtime
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | my.demo
58 | service-client
59 | 0.0.1-SNAPSHOT
60 |
61 |
62 | org.springframework.boot
63 | spring-boot-starter
64 |
65 |
66 | ch.qos.logback
67 | logback-classic
68 |
69 |
70 |
71 |
72 | org.fitnesse
73 | fitnesse
74 | 20200308
75 | provided
76 |
77 |
78 | mysql
79 | mysql-connector-java
80 | 8.0.18
81 |
82 |
83 |
--------------------------------------------------------------------------------
/fitnesse/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | docker run -d --net=mydemo --name fitnesse -p 8011:8011 mydemo/fitnesse:latest
--------------------------------------------------------------------------------
/fitnesse/src/main/java/my/demo/test/DbUtils.java:
--------------------------------------------------------------------------------
1 | package my.demo.test;
2 |
3 | import java.sql.Connection;
4 | import java.sql.DriverManager;
5 | import java.sql.ResultSet;
6 | import java.sql.SQLException;
7 | import java.sql.Statement;
8 |
9 | import org.springframework.beans.factory.annotation.Value;
10 | import org.springframework.stereotype.Component;
11 |
12 | /**
13 | * Simply
14 | */
15 | @Component
16 | public class DbUtils {
17 | @Value("${mydemo.mysql.host}")
18 | String host;
19 | @Value("${mydemo.mysql.port}")
20 | String port;
21 | @Value("${mydemo.mysql.user}")
22 | String user;
23 | @Value("${mydemo.mysql.password}")
24 | String password;
25 | @Value("${mydemo.userDb}")
26 | String userDb;
27 |
28 | public Connection getUserDbConnection() throws ClassNotFoundException, SQLException {
29 | Class.forName("com.mysql.cj.jdbc.Driver");
30 | String url = String.format("jdbc:mysql://%s:%s/%s?connectTimeout=2000&socketTimeout=2000&characterEncoding=utf8&useTimezone=true&serverTimezone=Asia/Shanghai&useSSL=false", host, port, userDb);
31 | return DriverManager.getConnection(url, user, password);
32 | }
33 | public int executeUpdate(Connection connection, String sql) throws SQLException {
34 | Statement stmt = null;
35 | int result = 0;
36 | try {
37 | stmt = connection.createStatement();
38 | result = stmt.executeUpdate(sql);
39 | } catch(Exception e) {
40 | e.printStackTrace();
41 | if(stmt!=null) stmt.close();
42 | } finally {
43 | if(stmt!=null) stmt.close();
44 | }
45 | return result;
46 | }
47 | public ResultSet execQuery(Connection connection, String sql) throws SQLException {
48 | Statement stmt = null;
49 | try {
50 | stmt = connection.createStatement();
51 | return stmt.executeQuery(sql);
52 | } catch(Exception e) {
53 | e.printStackTrace();
54 | if(stmt!=null) stmt.close();
55 | }
56 | return null;
57 | }
58 | }
--------------------------------------------------------------------------------
/fitnesse/src/main/java/my/demo/test/Manager.java:
--------------------------------------------------------------------------------
1 | package my.demo.test;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.WebApplicationType;
5 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
6 | import org.springframework.boot.builder.SpringApplicationBuilder;
7 | import org.springframework.context.ConfigurableApplicationContext;
8 | import org.springframework.context.annotation.ComponentScan;
9 | import org.springframework.context.annotation.Configuration;
10 |
11 | import com.alibaba.dubbo.config.annotation.Reference;
12 | import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
13 |
14 | import my.demo.service.ItemService;
15 | import my.demo.service.UserService;
16 |
17 | @Configuration
18 | @EnableAutoConfiguration
19 | @ComponentScan(basePackages={"my.demo.test"})
20 | @EnableDubbo(scanBasePackages = { "my.demo.test" })
21 | public class Manager {
22 | static ConfigurableApplicationContext context = null;
23 | @Reference
24 | UserService userService;
25 | @Reference
26 | ItemService itemService;
27 | private static void startSpringBoot() {
28 | context = new SpringApplicationBuilder(Manager.class).web(WebApplicationType.NONE).run();
29 | }
30 | public static UserService getUserService() {
31 | if(context==null) {
32 | synchronized (Manager.class) {
33 | if(context==null) {
34 | startSpringBoot();
35 | }
36 | }
37 | }
38 | return context.getBean(Manager.class).userService;
39 | }
40 | public static ItemService getItemService() {
41 | if(context==null) {
42 | synchronized (Manager.class) {
43 | if(context==null) {
44 | startSpringBoot();
45 | }
46 | }
47 | }
48 | return context.getBean(Manager.class).itemService;
49 | }
50 |
51 | @Autowired
52 | DbUtils db;
53 | public static DbUtils getDbUtils() {
54 | if(context==null) {
55 | synchronized (Manager.class) {
56 | if(context==null) {
57 | startSpringBoot();
58 | }
59 | }
60 | }
61 | return context.getBean(Manager.class).db;
62 | }
63 | }
--------------------------------------------------------------------------------
/fitnesse/src/main/java/my/demo/test/fixture/DeleteUserFromDb.java:
--------------------------------------------------------------------------------
1 | package my.demo.test.fixture;
2 |
3 | import java.sql.Connection;
4 | import java.sql.ResultSet;
5 | import java.sql.SQLException;
6 |
7 | import fit.ColumnFixture;
8 | import my.demo.test.DbUtils;
9 | import my.demo.test.Manager;
10 |
11 | public class DeleteUserFromDb extends ColumnFixture {
12 | private String mobile;
13 | public String delete() {
14 | DbUtils utils = Manager.getDbUtils();
15 | Connection connection = null;
16 | try {
17 | connection = utils.getUserDbConnection();
18 | //SQL injection risk!
19 | ResultSet rs = utils.execQuery(connection, "select user_id from usr_user_account where account='" + mobile + "'");
20 | int userId = 0;
21 | if(rs.next()) {
22 | userId = rs.getInt("user_id");
23 | }
24 | rs.close();
25 | if(userId<=0) return "OK";
26 | utils.executeUpdate(connection, "delete from usr_user_account where account='" + mobile + "'");
27 | utils.executeUpdate(connection, "delete from usr_user where user_id=" + userId);
28 | connection.close();
29 | return "OK";
30 | } catch (ClassNotFoundException | SQLException e) {
31 | if(connection!=null) {
32 | this.closeConnection(connection);
33 | }
34 | e.printStackTrace();
35 | return "SysError: " + e.getMessage();
36 | }
37 | }
38 | public void setMobile(String mobile) {
39 | this.mobile = mobile;
40 | }
41 | private void closeConnection(Connection con) {
42 | try {
43 | con.close();
44 | } catch (Exception e) { e.printStackTrace(); }
45 | }
46 | }
--------------------------------------------------------------------------------
/fitnesse/src/main/java/my/demo/test/fixture/ItemQueryTest.java:
--------------------------------------------------------------------------------
1 | package my.demo.test.fixture;
2 |
3 | import java.util.ArrayList;
4 |
5 | import fit.RowFixture;
6 | import my.demo.entity.Item;
7 | import my.demo.service.ItemService;
8 | import my.demo.service.ServiceResult;
9 | import my.demo.test.Manager;
10 |
11 | public class ItemQueryTest extends RowFixture {
12 | @Override
13 | public Object[] query() throws Exception {
14 | ItemService service = Manager.getItemService();
15 | ServiceResult> serviceResult = service.findItem();
16 | if(!serviceResult.isSuccess()) return new Object[] {};
17 | Object[] result = new Object[serviceResult.getResult().size()];
18 | for(int i=0; i getTargetClass() {
25 | return Item.class;
26 | }
27 | }
--------------------------------------------------------------------------------
/fitnesse/src/main/java/my/demo/test/fixture/UserRegisterAndLoginDetailTest.java:
--------------------------------------------------------------------------------
1 | package my.demo.test.fixture;
2 |
3 | import java.text.SimpleDateFormat;
4 |
5 | import com.fasterxml.jackson.core.JsonProcessingException;
6 | import com.fasterxml.jackson.databind.ObjectMapper;
7 |
8 | import my.demo.entity.User;
9 | import my.demo.service.ServiceResult;
10 | import my.demo.service.UserService;
11 | import my.demo.test.Manager;
12 |
13 | public class UserRegisterAndLoginDetailTest {
14 | private static final String SYS_ERROR = "SysError: ";
15 | private ServiceResult result = null;
16 | public void registerWithMobileAndPassword(String mobile, String password) {
17 | UserService service = Manager.getUserService();
18 | try {
19 | result = service.registerByMobile(mobile, password);
20 | } catch (Exception e) {
21 | result = new ServiceResult<>();
22 | result.fail(SYS_ERROR + e.getMessage());
23 | }
24 | }
25 | public void loginWithMobileAndPassword(String mobile, String password) {
26 | UserService service = Manager.getUserService();
27 | try {
28 | result = service.login(mobile, password);
29 | } catch (Exception e) {
30 | result = new ServiceResult<>();
31 | result.fail(SYS_ERROR + e.getMessage());
32 | }
33 | }
34 | public boolean success() {
35 | return result.isSuccess();
36 | }
37 | public long userIdIs() {
38 | return result.getResult() == null ? 0 : result.getResult().getUserId();
39 | }
40 | public String userMobileIs() {
41 | return result.getResult() == null ? "" : result.getResult().getMobile();
42 | }
43 | public String userNicknameIs() {
44 | return result.getResult() == null ? "" : result.getResult().getNickname();
45 | }
46 | public String returnedResult() {
47 | if(result==null) return "null";
48 | ObjectMapper mapper = new ObjectMapper();
49 | try {
50 | mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
51 | return mapper.writeValueAsString(result);
52 | } catch (JsonProcessingException e) {
53 | return SYS_ERROR + e.getMessage();
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/fitnesse/src/main/java/my/demo/test/fixture/UserRegisterAndLoginSummaryTest.java:
--------------------------------------------------------------------------------
1 | package my.demo.test.fixture;
2 |
3 | import my.demo.entity.User;
4 | import my.demo.service.ServiceResult;
5 | import my.demo.service.UserService;
6 | import my.demo.test.Manager;
7 |
8 | public class UserRegisterAndLoginSummaryTest {
9 | private String mobile;
10 | private String password;
11 | public void setMobile(String mobile) {
12 | this.mobile = mobile;
13 | }
14 | public void setPassword(String password) {
15 | this.password = password;
16 | }
17 | public String register() {
18 | UserService service = Manager.getUserService();
19 | ServiceResult result = null;
20 | try {
21 | result = service.registerByMobile(mobile, password);
22 | } catch(Exception e) {
23 | return "SysError: " + e.getMessage();
24 | }
25 | return result.isSuccess() ? "OK" : result.getMessage();
26 | }
27 | public String login() {
28 | UserService service = Manager.getUserService();
29 | ServiceResult result = null;
30 | try {
31 | result = service.login(mobile, password);
32 | } catch(Exception e) {
33 | return "SysError: " + e.getMessage();
34 | }
35 | return result.isSuccess() ? "OK" : result.getMessage();
36 | }
37 | }
--------------------------------------------------------------------------------
/fitnesse/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server.port: ${SERVICE_PORT:8090}
2 |
3 | spring:
4 | application:
5 | name: ${application.name}
6 | main:
7 | allow-bean-definition-overriding: true
8 | output:
9 | ansi:
10 | enabled: always
11 |
12 | dubbo:
13 | scan:
14 | basePackages: my.demo.test
15 | application: # see com.alibaba.dubbo.config.ApplicationConfig
16 | id: ${application.name}
17 | name: ${application.name}
18 | qosEnable: false
19 | registry: # see com.alibaba.dubbo.config.RegistryConfig
20 | address: nacos://${nacos.address}
21 |
22 | mydemo:
23 | mysql:
24 | host: ${mysql.host}
25 | port: ${mysql.port}
26 | user: ${mysql.user}
27 | password: ${mysql.password}
28 | userDb: ${db.user}
--------------------------------------------------------------------------------
/fitnesse/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | UTF-8
15 | ${CONSOLE_LOG_PATTERN:-%clr([%d{${LOG_DATEFORMAT_PATTERN:-yyMMdd HH:mm:ss.SSS}}]){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%-35.35logger{35}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
16 |
17 |
18 |
19 |
20 | UTF-8
21 |
22 | ${CONSOLE_LOG_PATTERN:-%clr([%d{${LOG_DATEFORMAT_PATTERN:-yyMMdd HH:mm:ss.SSS}}]){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} ${log.traceInfo}%clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/istio/deployment/mycat-statefulset.yaml:
--------------------------------------------------------------------------------
1 | kind: Service
2 | apiVersion: v1
3 | metadata:
4 | name: mycat-demo
5 | spec:
6 | type: NodePort # Expose service port to host machine
7 | ports:
8 | - name: mysql-data # Data port in Mycat
9 | port: 8066
10 | targetPort: 8066
11 | nodePort: 30066 # Expose service port to host machine
12 | - name: mysql-mnt # Management port in Mycat
13 | port: 9066
14 | targetPort: 9066
15 | nodePort: 30067
16 | selector:
17 | app: mycat-demo
18 | ---
19 | apiVersion: apps/v1
20 | kind: StatefulSet
21 | metadata:
22 | name: mycat-demo
23 | spec:
24 | replicas: 1
25 | serviceName: mycat-demo
26 | selector:
27 | matchLabels:
28 | app: mycat-demo
29 | template:
30 | metadata:
31 | labels:
32 | app: mycat-demo
33 | version: 1.6.7.3
34 | spec:
35 | containers:
36 | - name: mycat-demo
37 | image: mydemo/mycat:1.6.7.3
38 | imagePullPolicy: IfNotPresent
39 | env:
40 | - name: MYSQL_HOST
41 | value: "db-demo.default.svc.cluster.local"
42 | ports:
43 | - containerPort: 8066
44 | - containerPort: 9066
45 | readinessProbe: # Check whether Mycat is ready
46 | #tcpSocket: # Wait until TCP port is opened
47 | # port: 8066
48 | exec: # Use exec command to avoid connecting to 8066
49 | command: ["sh", "-c", "COUNT=`netstat -antp tcp | grep 8066 | grep LISTEN -c`; if [ $COUNT -eq 1 ]; then exit 0; else exit 1; fi"]
50 | initialDelaySeconds: 5 # Wait initialDelaySeconds to check the first time
51 | periodSeconds: 5 # Wait periodSeconds to check next time
52 | timeoutSeconds: 2 # Timeout for check process
53 | # initContainers:
54 | # - name: wait-deps
55 | # image: busybox
56 | # imagePullPolicy: IfNotPresent
57 | # 1. Wait PODs of dependencies to be READY.
58 | # 2. Wait services of dependencies to be READY, including service DNS being available.
59 | # command: ['sh', '-c', 'until nslookup db-demo; do sleep 3; done;']
--------------------------------------------------------------------------------
/istio/deployment/mysql-statefulset.yaml:
--------------------------------------------------------------------------------
1 | kind: Service
2 | apiVersion: v1
3 | metadata:
4 | name: db-demo
5 | spec:
6 | type: NodePort # Expose service port to host machine
7 | ports:
8 | - name: mysql
9 | port: 3306
10 | targetPort: 3306
11 | nodePort: 30006 # Expose service port to host machine
12 | selector:
13 | app: db-demo
14 | ---
15 | apiVersion: apps/v1
16 | kind: StatefulSet
17 | metadata:
18 | name: db-demo
19 | spec:
20 | replicas: 1
21 | serviceName: db-demo
22 | selector:
23 | matchLabels:
24 | app: db-demo
25 | template:
26 | metadata:
27 | labels:
28 | app: db-demo
29 | version: 5.7.18
30 | spec:
31 | containers:
32 | - name: db-demo
33 | image: mydemo/mysql:5.7.18
34 | imagePullPolicy: IfNotPresent
35 | env:
36 | - name: MYSQL_ROOT_PASSWORD
37 | value: "123"
38 | ports:
39 | - containerPort: 3306
40 | readinessProbe: # Check whether MySQL service is ready
41 | exec:
42 | # There's problems in the following readiness probe command:
43 | # The container mysql:5.7.18 starts MySQL process for initialization, then stop and restart it.
44 | # The probe command can success in initialization process, it causes the POD to be READY, and other
45 | # services will create long lived connections to MySQL (by connection pool). After MySQL restarts,
46 | # these connections are broken, causes "Connection refused" exception.
47 | # The initialDelaySeconds is set to an estimated value, but it variates in different environment.
48 | command: ["mysql", "-hlocalhost", "-uroot", "-p123", "-P3306", "--database", "skywalking", "-e", "SELECT 1"]
49 | initialDelaySeconds: 15 # Wait initialDelaySeconds to check the first time
50 | periodSeconds: 5 # Wait periodSeconds to check next time
51 | timeoutSeconds: 2 # Timeout for check process
52 |
--------------------------------------------------------------------------------
/istio/deployment/nacos-statefulset.yaml:
--------------------------------------------------------------------------------
1 | kind: Service
2 | apiVersion: v1
3 | metadata:
4 | name: pub-nacos
5 | spec:
6 | type: NodePort # Expose service port to host machine
7 | ports:
8 | - name: http-nacos
9 | port: 8848
10 | targetPort: 8848
11 | nodePort: 30048 # Expose service port to host machine
12 | selector:
13 | app: pub-nacos
14 | ---
15 | apiVersion: apps/v1
16 | kind: StatefulSet
17 | metadata:
18 | name: pub-nacos
19 | spec:
20 | replicas: 1
21 | serviceName: pub-nacos
22 | selector:
23 | matchLabels:
24 | app: pub-nacos
25 | template:
26 | metadata:
27 | labels:
28 | app: pub-nacos
29 | version: 1.1.4
30 | spec:
31 | containers:
32 | - name: pub-nacos
33 | image: mydemo/nacos:1.1.4
34 | imagePullPolicy: IfNotPresent
35 | env:
36 | - name: MYSQL_HOST
37 | value: "db-demo.default.svc.cluster.local"
38 | ports:
39 | - containerPort: 8848
40 | readinessProbe: # Check whether Nacos is ready
41 | httpGet: # Wait until HTTP status ok
42 | path: /nacos
43 | port: 8848
44 | initialDelaySeconds: 3 # Wait initialDelaySeconds to check the first time
45 | periodSeconds: 5 # Wait periodSeconds to check next time
46 | timeoutSeconds: 2 # Timeout for check process
47 | # initContainers:
48 | # - name: wait-deps
49 | # image: busybox
50 | # imagePullPolicy: IfNotPresent
51 | # 1. Wait PODs of dependencies to be READY.
52 | # 2. Wait services of dependencies to be READY, including service DNS being available.
53 | # command: ['sh', '-c', 'until nslookup db-demo; do sleep 3; done;']
--------------------------------------------------------------------------------
/istio/deployment/svc-item-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: svc-item
5 | spec:
6 | replicas: 1
7 | selector:
8 | matchLabels:
9 | app: svc-item
10 | template:
11 | metadata:
12 | labels:
13 | app: svc-item
14 | version: latest
15 | spec:
16 | containers:
17 | - name: svc-item
18 | image: mydemo/item
19 | imagePullPolicy: IfNotPresent
20 | env:
21 | - name: NACOS_HOST
22 | value: "pub-nacos.default.svc.cluster.local"
23 | - name: ZIPKIN_HOST
24 | value: "pub-zipkin.default.svc.cluster.local"
25 | - name: SERVICE_HOST # Use POD IP to register Dubbo service
26 | valueFrom:
27 | fieldRef:
28 | fieldPath: status.podIP
29 | - name: SERVICE_PORT
30 | value: "20880"
31 | ports:
32 | - containerPort: 20880
33 | readinessProbe: # Check whether Item Service is ready
34 | #tcpSocket: # Wait until TCP port is opened
35 | # port: 20880
36 | # tcpSocket probe will connect and disconnect to 20880 periodically,
37 | # cause massive Dubbo logs: "[DUBBO] disconnected from /10.1.0.1:33994 ..."
38 | exec:
39 | command: ["sh", "-c", "COUNT=`netstat -antp tcp|grep 20880|grep LISTEN -c`; if [ $COUNT -eq 1 ]; then exit 0; else exit 1; fi"]
40 | initialDelaySeconds: 3 # Wait initialDelaySeconds to check the first time
41 | periodSeconds: 5 # Wait periodSeconds to check next time
42 | timeoutSeconds: 1 # Timeout for check process
43 | # initContainers:
44 | # - name: wait-deps
45 | # image: busybox
46 | # imagePullPolicy: IfNotPresent
47 | # 1. Wait PODs of dependencies to be READY.
48 | # 2. Wait services of dependencies to be READY, including service DNS being available.
49 | # command: ['sh', '-c', 'until nslookup pub-nacos; do sleep 3; done;']
--------------------------------------------------------------------------------
/istio/deployment/svc-order-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: svc-order
5 | spec:
6 | replicas: 1
7 | selector:
8 | matchLabels:
9 | app: svc-order
10 | template:
11 | metadata:
12 | labels:
13 | app: svc-order
14 | version: latest
15 | spec:
16 | containers:
17 | - name: svc-order
18 | image: mydemo/order
19 | imagePullPolicy: IfNotPresent
20 | env:
21 | - name: MYSQL_HOST
22 | value: "mycat-demo.default.svc.cluster.local"
23 | - name: NACOS_HOST
24 | value: "pub-nacos.default.svc.cluster.local"
25 | - name: ZIPKIN_HOST
26 | value: "pub-zipkin.default.svc.cluster.local"
27 | - name: SERVICE_HOST # Use POD IP to register Dubbo service
28 | valueFrom:
29 | fieldRef:
30 | fieldPath: status.podIP
31 | - name: SERVICE_PORT
32 | value: "20880"
33 | ports:
34 | - containerPort: 20880
35 | readinessProbe: # Check whether User Service is ready
36 | #tcpSocket: # Wait until TCP port is opened
37 | # port: 20880
38 | # tcpSocket probe will connect and disconnect to 20880 periodically,
39 | # cause massive Dubbo logs: "[DUBBO] disconnected from /10.1.0.1:33994 ..."
40 | exec:
41 | command: ["sh", "-c", "COUNT=`netstat -antp tcp|grep 20880|grep LISTEN -c`; if [ $COUNT -eq 1 ]; then exit 0; else exit 1; fi"]
42 | initialDelaySeconds: 3 # Wait initialDelaySeconds to check the first time
43 | periodSeconds: 5 # Wait periodSeconds to check next time
44 | timeoutSeconds: 1 # Timeout for check process
45 | # initContainers:
46 | # - name: wait-deps
47 | # image: busybox
48 | # imagePullPolicy: IfNotPresent
49 | # 1. Wait PODs of dependencies to be READY.
50 | # 2. Wait services of dependencies to be READY, including service DNS being available.
51 | # command: ['sh', '-c', 'until nslookup pub-nacos; do sleep 3; done; until nslookup mycat-demo; do sleep 3; done;']
--------------------------------------------------------------------------------
/istio/deployment/svc-stock-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: svc-stock
5 | spec:
6 | replicas: 1
7 | selector:
8 | matchLabels:
9 | app: svc-stock
10 | template:
11 | metadata:
12 | labels:
13 | app: svc-stock
14 | version: latest
15 | spec:
16 | containers:
17 | - name: svc-stock
18 | image: mydemo/stock
19 | imagePullPolicy: IfNotPresent
20 | env:
21 | - name: NACOS_HOST
22 | value: "pub-nacos.default.svc.cluster.local"
23 | - name: ZIPKIN_HOST
24 | value: "pub-zipkin.default.svc.cluster.local"
25 | - name: SERVICE_HOST # Use POD IP to register Dubbo service
26 | valueFrom:
27 | fieldRef:
28 | fieldPath: status.podIP
29 | - name: SERVICE_PORT
30 | value: "20880"
31 | ports:
32 | - containerPort: 20880
33 | readinessProbe: # Check whether Stock Service is ready
34 | #tcpSocket: # Wait until TCP port is opened
35 | # port: 20880
36 | # tcpSocket probe will connect and disconnect to 20880 periodically,
37 | # cause massive Dubbo logs: "[DUBBO] disconnected from /10.1.0.1:33994 ..."
38 | exec:
39 | command: ["sh", "-c", "COUNT=`netstat -antp tcp|grep 20880|grep LISTEN -c`; if [ $COUNT -eq 1 ]; then exit 0; else exit 1; fi"]
40 | initialDelaySeconds: 3 # Wait initialDelaySeconds to check the first time
41 | periodSeconds: 5 # Wait periodSeconds to check next time
42 | timeoutSeconds: 1 # Timeout for check process
43 | # initContainers:
44 | # - name: wait-deps
45 | # image: busybox
46 | # imagePullPolicy: IfNotPresent
47 | # 1. Wait PODs of dependencies to be READY.
48 | # 2. Wait services of dependencies to be READY, including service DNS being available.
49 | # command: ['sh', '-c', 'until nslookup pub-nacos; do sleep 3; done;']
--------------------------------------------------------------------------------
/istio/deployment/svc-user-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: svc-user
5 | spec:
6 | replicas: 2
7 | selector:
8 | matchLabels:
9 | app: svc-user
10 | template:
11 | metadata:
12 | labels:
13 | app: svc-user
14 | version: latest
15 | spec:
16 | containers:
17 | - name: svc-user
18 | image: mydemo/user
19 | imagePullPolicy: IfNotPresent
20 | env:
21 | - name: MYSQL_HOST
22 | value: "mycat-demo.default.svc.cluster.local"
23 | - name: NACOS_HOST
24 | value: "pub-nacos.default.svc.cluster.local"
25 | - name: ZIPKIN_HOST
26 | value: "pub-zipkin.default.svc.cluster.local"
27 | - name: SERVICE_HOST # Use POD IP to register Dubbo service
28 | valueFrom:
29 | fieldRef:
30 | fieldPath: status.podIP
31 | - name: SERVICE_PORT
32 | value: "20880"
33 | ports:
34 | - containerPort: 20880
35 | readinessProbe: # Check whether User Service is ready
36 | #tcpSocket: # Wait until TCP port is opened
37 | # port: 20880
38 | # tcpSocket probe will connect and disconnect to 20880 periodically,
39 | # cause massive Dubbo logs: "[DUBBO] disconnected from /10.1.0.1:33994 ..."
40 | exec:
41 | command: ["sh", "-c", "COUNT=`netstat -antp tcp|grep 20880|grep LISTEN -c`; if [ $COUNT -eq 1 ]; then exit 0; else exit 1; fi"]
42 | initialDelaySeconds: 3 # Wait initialDelaySeconds to check the first time
43 | periodSeconds: 5 # Wait periodSeconds to check next time
44 | timeoutSeconds: 1 # Timeout for check process
45 | # initContainers:
46 | # - name: wait-deps
47 | # image: busybox
48 | # imagePullPolicy: IfNotPresent
49 | # 1. Wait PODs of dependencies to be READY.
50 | # 2. Wait services of dependencies to be READY, including service DNS being available.
51 | # command: ['sh', '-c', 'until nslookup pub-nacos; do sleep 3; done; until nslookup mycat-demo; do sleep 3; done;']
52 |
--------------------------------------------------------------------------------
/istio/deployment/zipkin-statefulset.yaml:
--------------------------------------------------------------------------------
1 | kind: Service
2 | apiVersion: v1
3 | metadata:
4 | name: pub-zipkin
5 | spec:
6 | type: NodePort # Expose service port to host machine
7 | ports:
8 | - name: http-zipkin
9 | port: 9411
10 | targetPort: 9411
11 | nodePort: 30041 # Expose service port to host machine
12 | selector:
13 | app: pub-zipkin
14 | ---
15 | apiVersion: apps/v1
16 | kind: StatefulSet
17 | metadata:
18 | name: pub-zipkin
19 | spec:
20 | replicas: 1
21 | serviceName: pub-zipkin
22 | selector:
23 | matchLabels:
24 | app: pub-zipkin
25 | template:
26 | metadata:
27 | labels:
28 | app: pub-zipkin
29 | version: 2.19.2
30 | spec:
31 | containers:
32 | - name: pub-zipkin
33 | image: mydemo/zipkin:2.19.2
34 | imagePullPolicy: IfNotPresent
35 | env:
36 | - name: MYSQL_HOST
37 | value: "db-demo.default.svc.cluster.local"
38 | ports:
39 | - containerPort: 9411
40 | readinessProbe: # Check whether ZipKin is ready
41 | httpGet: # Wait until HTTP status ok
42 | path: /zipkin
43 | port: 9411
44 | initialDelaySeconds: 3 # Wait initialDelaySeconds to check the first time
45 | periodSeconds: 5 # Wait periodSeconds to check next time
46 | timeoutSeconds: 2 # Timeout for check process
47 | # initContainers:
48 | # - name: wait-deps
49 | # image: busybox
50 | # imagePullPolicy: IfNotPresent
51 | # 1. Wait PODs of dependencies to be READY.
52 | # 2. Wait services of dependencies to be READY, including service DNS being available.
53 | # command: ['sh', '-c', 'until nslookup db-demo; do sleep 3; done;']
--------------------------------------------------------------------------------
/istio/undeploy-istio.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | kubectl delete Deployment web-shop-v1 web-shop-v2 svc-order svc-user svc-stock svc-item
4 | kubectl delete StatefulSet pub-zipkin pub-nacos mycat-demo db-demo
5 | kubectl delete Service web-shop pub-zipkin pub-nacos mycat-demo db-demo
6 | kubectl delete VirtualService web-shop
7 | kubectl delete DestinationRule web-shop
8 | kubectl delete Gateway web-shop-gateway -n istio-system
--------------------------------------------------------------------------------
/item-service/Dockerfile.default:
--------------------------------------------------------------------------------
1 | FROM mydemo/openjdk:8-jre-alpine
2 |
3 | WORKDIR /home
4 | ENV NACOS_HOST=nacos ZIPKIN_HOST=zipkin SERVICE_PORT=20880
5 | ADD ./target/item-service-0.0.1-SNAPSHOT.jar /home/
6 | EXPOSE 20880
7 | ENTRYPOINT ["java", "-jar", "/home/item-service-0.0.1-SNAPSHOT.jar"]
--------------------------------------------------------------------------------
/item-service/Dockerfile.skywalking:
--------------------------------------------------------------------------------
1 | FROM mydemo/skywalking-base:6.6.0 AS build
2 |
3 | WORKDIR /home/skywalking
4 | RUN rm -rf oap-libs webapp
5 |
6 | FROM mydemo/openjdk:8-jre-alpine
7 |
8 | COPY --from=build /home/skywalking /home/skywalking
9 | ENV NACOS_HOST=nacos SKYWALKING_HOST=skywalking-oap SKYWALKING_PORT=11800 SERVICE_PORT=20880
10 | ADD ./target/item-service-0.0.1-SNAPSHOT.jar /home/
11 | ADD ./docker-entrypoint.sh /home/
12 | EXPOSE 20880
13 | ENTRYPOINT ["/home/docker-entrypoint.sh", "-javaagent:/home/skywalking/agent/skywalking-agent.jar", "-Dskywalking.agent.service_name=item-svc", "-Dskywalking.collector.backend_service=$SW_AGENT_COLLECTOR_BACKEND_SERVICES", "-jar", "/home/item-service-0.0.1-SNAPSHOT.jar"]
--------------------------------------------------------------------------------
/item-service/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Dockerfile Maven: https://github.com/spotify/dockerfile-maven
4 | # Use shell script to build Docker image because additional process is required in case of SkyWalking enabled
5 |
6 | # The value will be set by package.sh
7 | APM=zipkin
8 |
9 | DIR=`dirname "$0"`
10 | cd $DIR
11 |
12 | if [ "$APM" = "skywalking" ]; then
13 | cp Dockerfile.skywalking Dockerfile
14 | else
15 | cp Dockerfile.default Dockerfile
16 | fi
17 |
18 | docker build -t mydemo/item .
19 | rm -rf Dockerfile
--------------------------------------------------------------------------------
/item-service/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SW_AGENT_COLLECTOR_BACKEND_SERVICES=$SKYWALKING_HOST:$SKYWALKING_PORT
4 |
5 | set -ex
6 | eval java $@
--------------------------------------------------------------------------------
/item-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | my.demo
9 | mydemo-parent
10 | 0.0.1-SNAPSHOT
11 |
12 |
13 | item-service
14 |
15 |
16 | item
17 |
18 |
19 |
20 |
21 |
22 | src/main/resources
23 | true
24 |
25 | application.yml
26 | logback.xml
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | my.demo
35 | service-client
36 | 0.0.1-SNAPSHOT
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-starter
41 |
42 |
43 |
--------------------------------------------------------------------------------
/item-service/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | docker run -d --net=mydemo --name item -e SERVICE_HOST=item -e NACOS_HOST=nacos -e ZIPKIN_HOST=zipkin -e SKYWALKING_HOST=skywalking-oap mydemo/item
--------------------------------------------------------------------------------
/item-service/src/main/java/my/demo/service/item/Application.java:
--------------------------------------------------------------------------------
1 | package my.demo.service.item;
2 |
3 | import org.springframework.boot.WebApplicationType;
4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
5 | import org.springframework.boot.builder.SpringApplicationBuilder;
6 | import org.springframework.context.annotation.ComponentScan;
7 | import org.springframework.context.annotation.Configuration;
8 |
9 | import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
10 |
11 | @Configuration
12 | @EnableAutoConfiguration
13 | @ComponentScan(basePackages={"my.demo.service.item", "my.demo.utils"})
14 | @EnableDubbo(scanBasePackages = { "my.demo.service.item" })
15 | public class Application {
16 | public static void main(String[] args) {
17 | new SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE).run(args);
18 | }
19 | }
--------------------------------------------------------------------------------
/item-service/src/main/java/my/demo/service/item/ItemServiceImpl.java:
--------------------------------------------------------------------------------
1 | package my.demo.service.item;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | import com.alibaba.dubbo.config.annotation.Service;
8 |
9 | import my.demo.entity.Item;
10 | import my.demo.service.ItemService;
11 | import my.demo.service.ServiceResult;
12 | import my.demo.utils.MyDemoUtils;
13 |
14 | @Service
15 | public class ItemServiceImpl implements ItemService {
16 | private static Map items = new HashMap<>();
17 |
18 | static {
19 | Item item = new Item();
20 | item.setId(10201);
21 | item.setTitle("小米电视4X/4S 65英寸PRO 4K超高清 HDR 蓝牙语音人工智能网络液晶平板电视");
22 | item.setPrice(2599);
23 | items.put(item.getId(), item);
24 |
25 | item = new Item();
26 | item.setId(20912);
27 | item.setTitle("华为(HUAWEI)MateBook 13 锐龙版 全面屏轻薄性能笔记本电脑(AMD R5 8+512GB 2K 集显)银");
28 | item.setPrice(4099);
29 | items.put(item.getId(), item);
30 |
31 | item = new Item();
32 | item.setId(98143);
33 | item.setTitle("ECCO爱步2019秋冬新款休闲女鞋 运动户外女士鞋拼色低帮鞋平底 适动836283");
34 | item.setPrice(1999);
35 | items.put(item.getId(), item);
36 |
37 | item = new Item();
38 | item.setId(65982);
39 | item.setTitle("五粮液股份公司出品 五粮精酿 礼鉴珍品 52度 浓香型白酒 500ml");
40 | item.setPrice(599);
41 | items.put(item.getId(), item);
42 |
43 | item = new Item();
44 | item.setId(30975);
45 | item.setTitle("西铁城(CITIZEN)手表 蓝天使男士手表石英光动能多局电波表运动腕表AT8020-54L");
46 | item.setPrice(3920);
47 | items.put(item.getId(), item);
48 | }
49 |
50 | @Override
51 | public ServiceResult> findItem() {
52 | return new ServiceResult<>(new ArrayList<>(items.values()));
53 | }
54 |
55 | @Override
56 | public ServiceResult- getItem(int itemId) {
57 | MyDemoUtils.tag("itemId", itemId);
58 | Item item = items.get(itemId);
59 | if(item==null) {
60 | return new ServiceResult
- ().fail("Item " + itemId + " not found");
61 | } else {
62 | return new ServiceResult<>(item);
63 | }
64 | }
65 |
66 | }
--------------------------------------------------------------------------------
/item-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | main:
3 | allow-bean-definition-overriding: true
4 | output:
5 | ansi:
6 | enabled: always
7 |
8 | dubbo:
9 | application: # see com.alibaba.dubbo.config.ApplicationConfig
10 | id: ${application.name}-srv
11 | name: ${application.name}-srv
12 | qosEnable: false
13 | protocol: # see com.alibaba.dubbo.config.ProtocolConfig
14 | id: dubbo
15 | name: dubbo
16 | host: ${SERVICE_HOST:localhost} # Use POD IP to register Dubbo service
17 | port: ${SERVICE_PORT:20880}
18 | threads: 3
19 | iothreads: 1
20 | server: netty
21 | client: netty
22 | status: server
23 | serialization: fst
24 | queues: 0
25 | keepAlive: true
26 | registry: # see com.alibaba.dubbo.config.RegistryConfig
27 | address: nacos://${nacos.address}
28 | check: false
29 | provider:
30 | cluster: failfast
31 | retries: 0
32 | loadbalance: roundrobin
33 | timeout: 10000
34 | filter: ${dubbo.filter}
35 |
36 | zipkin:
37 | server: ${zipkin.base-url}/api/v2/spans
38 | connectTimeout: 5000
39 | readTimeout: 5000
--------------------------------------------------------------------------------
/item-service/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | UTF-8
15 | ${CONSOLE_LOG_PATTERN:-%clr([%d{${LOG_DATEFORMAT_PATTERN:-yyMMdd HH:mm:ss.SSS}}]){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%-35.35logger{35}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
16 |
17 |
18 |
19 |
20 | UTF-8
21 |
22 | ${CONSOLE_LOG_PATTERN:-%clr([%d{${LOG_DATEFORMAT_PATTERN:-yyMMdd HH:mm:ss.SSS}}]){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} ${log.traceInfo}%clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/k8s/deployment/mycat-statefulset.yaml:
--------------------------------------------------------------------------------
1 | kind: Service
2 | apiVersion: v1
3 | metadata:
4 | name: mycat-demo
5 | spec:
6 | type: NodePort # Expose service port to host machine
7 | ports:
8 | - name: mysql-data # Data port in Mycat
9 | port: 8066
10 | targetPort: 8066
11 | nodePort: 30066 # Expose service port to host machine
12 | - name: mysql-mnt # Management port in Mycat
13 | port: 9066
14 | targetPort: 9066
15 | nodePort: 30067
16 | selector:
17 | app: mycat-demo
18 | ---
19 | apiVersion: apps/v1
20 | kind: StatefulSet
21 | metadata:
22 | name: mycat-demo
23 | spec:
24 | replicas: 1
25 | serviceName: mycat-demo
26 | selector:
27 | matchLabels:
28 | app: mycat-demo
29 | template:
30 | metadata:
31 | labels:
32 | app: mycat-demo
33 | version: 1.6.7.3
34 | spec:
35 | containers:
36 | - name: mycat-demo
37 | image: mydemo/mycat:1.6.7.3
38 | imagePullPolicy: IfNotPresent
39 | env:
40 | - name: MYSQL_HOST
41 | value: "db-demo.default.svc.cluster.local"
42 | ports:
43 | - containerPort: 8066
44 | - containerPort: 9066
45 | readinessProbe: # Check whether Mycat is ready
46 | #tcpSocket: # Wait until TCP port is opened
47 | # port: 8066
48 | exec: # Use exec command to avoid connecting to 8066
49 | command: ["sh", "-c", "COUNT=`netstat -antp tcp | grep 8066 | grep LISTEN -c`; if [ $COUNT -eq 1 ]; then exit 0; else exit 1; fi"]
50 | initialDelaySeconds: 5 # Wait initialDelaySeconds to check the first time
51 | periodSeconds: 5 # Wait periodSeconds to check next time
52 | timeoutSeconds: 2 # Timeout for check process
53 | # initContainers:
54 | # - name: wait-deps
55 | # image: busybox
56 | # imagePullPolicy: IfNotPresent
57 | # 1. Wait PODs of dependencies to be READY.
58 | # 2. Wait services of dependencies to be READY, including service DNS being available.
59 | # command: ['sh', '-c', 'until nslookup db-demo; do sleep 3; done;']
--------------------------------------------------------------------------------
/k8s/deployment/mysql-statefulset.yaml:
--------------------------------------------------------------------------------
1 | kind: Service
2 | apiVersion: v1
3 | metadata:
4 | name: db-demo
5 | spec:
6 | type: NodePort # Expose service port to host machine
7 | ports:
8 | - name: mysql
9 | port: 3306
10 | targetPort: 3306
11 | nodePort: 30006 # Expose service port to host machine
12 | selector:
13 | app: db-demo
14 | ---
15 | apiVersion: apps/v1
16 | kind: StatefulSet
17 | metadata:
18 | name: db-demo
19 | spec:
20 | replicas: 1
21 | serviceName: db-demo
22 | selector:
23 | matchLabels:
24 | app: db-demo
25 | template:
26 | metadata:
27 | labels:
28 | app: db-demo
29 | version: 5.7.18
30 | spec:
31 | containers:
32 | - name: db-demo
33 | image: mydemo/mysql:5.7.18
34 | imagePullPolicy: IfNotPresent
35 | env:
36 | - name: MYSQL_ROOT_PASSWORD
37 | value: "123"
38 | ports:
39 | - containerPort: 3306
40 | readinessProbe: # Check whether MySQL service is ready
41 | exec:
42 | # There's problems in the following readiness probe command:
43 | # The container mysql:5.7.18 starts MySQL process for initialization, then stop and restart it.
44 | # The probe command can success in initialization process, it causes the POD to be READY, and other
45 | # services will create long lived connections to MySQL (by connection pool). After MySQL restarts,
46 | # these connections are broken, causes "Connection refused" exception.
47 | # The initialDelaySeconds is set to an estimated value, but it variates in different environment.
48 | command: ["mysql", "-hlocalhost", "-uroot", "-p123", "-P3306", "--database", "skywalking", "-e", "SELECT 1"]
49 | initialDelaySeconds: 15 # Wait initialDelaySeconds to check the first time
50 | periodSeconds: 5 # Wait periodSeconds to check next time
51 | timeoutSeconds: 2 # Timeout for check process
52 |
--------------------------------------------------------------------------------
/k8s/deployment/nacos-statefulset.yaml:
--------------------------------------------------------------------------------
1 | kind: Service
2 | apiVersion: v1
3 | metadata:
4 | name: pub-nacos
5 | spec:
6 | type: NodePort # Expose service port to host machine
7 | ports:
8 | - name: http-nacos
9 | port: 8848
10 | targetPort: 8848
11 | nodePort: 30048 # Expose service port to host machine
12 | selector:
13 | app: pub-nacos
14 | ---
15 | apiVersion: apps/v1
16 | kind: StatefulSet
17 | metadata:
18 | name: pub-nacos
19 | spec:
20 | replicas: 1
21 | serviceName: pub-nacos
22 | selector:
23 | matchLabels:
24 | app: pub-nacos
25 | template:
26 | metadata:
27 | labels:
28 | app: pub-nacos
29 | version: 1.1.4
30 | spec:
31 | containers:
32 | - name: pub-nacos
33 | image: mydemo/nacos:1.1.4
34 | imagePullPolicy: IfNotPresent
35 | env:
36 | - name: MYSQL_HOST
37 | value: "db-demo.default.svc.cluster.local"
38 | ports:
39 | - containerPort: 8848
40 | readinessProbe: # Check whether Nacos is ready
41 | httpGet: # Wait until HTTP status ok
42 | path: /nacos
43 | port: 8848
44 | initialDelaySeconds: 3 # Wait initialDelaySeconds to check the first time
45 | periodSeconds: 5 # Wait periodSeconds to check next time
46 | timeoutSeconds: 2 # Timeout for check process
47 | # initContainers:
48 | # - name: wait-deps
49 | # image: busybox
50 | # imagePullPolicy: IfNotPresent
51 | # 1. Wait PODs of dependencies to be READY.
52 | # 2. Wait services of dependencies to be READY, including service DNS being available.
53 | # command: ['sh', '-c', 'until nslookup db-demo; do sleep 3; done;']
--------------------------------------------------------------------------------
/k8s/deployment/svc-item-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: svc-item
5 | spec:
6 | replicas: 1
7 | selector:
8 | matchLabels:
9 | app: svc-item
10 | template:
11 | metadata:
12 | labels:
13 | app: svc-item
14 | version: latest
15 | spec:
16 | containers:
17 | - name: svc-item
18 | image: mydemo/item
19 | imagePullPolicy: IfNotPresent
20 | env:
21 | - name: NACOS_HOST
22 | value: "pub-nacos.default.svc.cluster.local"
23 | - name: ZIPKIN_HOST
24 | value: "pub-zipkin.default.svc.cluster.local"
25 | - name: SERVICE_HOST # Use POD IP to register Dubbo service
26 | valueFrom:
27 | fieldRef:
28 | fieldPath: status.podIP
29 | - name: SERVICE_PORT
30 | value: "20880"
31 | ports:
32 | - containerPort: 20880
33 | readinessProbe: # Check whether Item Service is ready
34 | #tcpSocket: # Wait until TCP port is opened
35 | # port: 20880
36 | # tcpSocket probe will connect and disconnect to 20880 periodically,
37 | # cause massive Dubbo logs: "[DUBBO] disconnected from /10.1.0.1:33994 ..."
38 | exec:
39 | command: ["sh", "-c", "COUNT=`netstat -antp tcp|grep 20880|grep LISTEN -c`; if [ $COUNT -eq 1 ]; then exit 0; else exit 1; fi"]
40 | initialDelaySeconds: 3 # Wait initialDelaySeconds to check the first time
41 | periodSeconds: 5 # Wait periodSeconds to check next time
42 | timeoutSeconds: 1 # Timeout for check process
43 | # initContainers:
44 | # - name: wait-deps
45 | # image: busybox
46 | # imagePullPolicy: IfNotPresent
47 | # 1. Wait PODs of dependencies to be READY.
48 | # 2. Wait services of dependencies to be READY, including service DNS being available.
49 | # command: ['sh', '-c', 'until nslookup pub-nacos; do sleep 3; done;']
--------------------------------------------------------------------------------
/k8s/deployment/svc-order-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: svc-order
5 | spec:
6 | replicas: 1
7 | selector:
8 | matchLabels:
9 | app: svc-order
10 | template:
11 | metadata:
12 | labels:
13 | app: svc-order
14 | version: latest
15 | spec:
16 | containers:
17 | - name: svc-order
18 | image: mydemo/order
19 | imagePullPolicy: IfNotPresent
20 | env:
21 | - name: MYSQL_HOST
22 | value: "mycat-demo.default.svc.cluster.local"
23 | - name: NACOS_HOST
24 | value: "pub-nacos.default.svc.cluster.local"
25 | - name: ZIPKIN_HOST
26 | value: "pub-zipkin.default.svc.cluster.local"
27 | - name: SERVICE_HOST # Use POD IP to register Dubbo service
28 | valueFrom:
29 | fieldRef:
30 | fieldPath: status.podIP
31 | - name: SERVICE_PORT
32 | value: "20880"
33 | ports:
34 | - containerPort: 20880
35 | readinessProbe: # Check whether User Service is ready
36 | #tcpSocket: # Wait until TCP port is opened
37 | # port: 20880
38 | # tcpSocket probe will connect and disconnect to 20880 periodically,
39 | # cause massive Dubbo logs: "[DUBBO] disconnected from /10.1.0.1:33994 ..."
40 | exec:
41 | command: ["sh", "-c", "COUNT=`netstat -antp tcp|grep 20880|grep LISTEN -c`; if [ $COUNT -eq 1 ]; then exit 0; else exit 1; fi"]
42 | initialDelaySeconds: 3 # Wait initialDelaySeconds to check the first time
43 | periodSeconds: 5 # Wait periodSeconds to check next time
44 | timeoutSeconds: 1 # Timeout for check process
45 | # initContainers:
46 | # - name: wait-deps
47 | # image: busybox
48 | # imagePullPolicy: IfNotPresent
49 | # 1. Wait PODs of dependencies to be READY.
50 | # 2. Wait services of dependencies to be READY, including service DNS being available.
51 | # command: ['sh', '-c', 'until nslookup pub-nacos; do sleep 3; done; until nslookup mycat-demo; do sleep 3; done;']
--------------------------------------------------------------------------------
/k8s/deployment/svc-stock-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: svc-stock
5 | spec:
6 | replicas: 1
7 | selector:
8 | matchLabels:
9 | app: svc-stock
10 | template:
11 | metadata:
12 | labels:
13 | app: svc-stock
14 | version: latest
15 | spec:
16 | containers:
17 | - name: svc-stock
18 | image: mydemo/stock
19 | imagePullPolicy: IfNotPresent
20 | env:
21 | - name: NACOS_HOST
22 | value: "pub-nacos.default.svc.cluster.local"
23 | - name: ZIPKIN_HOST
24 | value: "pub-zipkin.default.svc.cluster.local"
25 | - name: SERVICE_HOST # Use POD IP to register Dubbo service
26 | valueFrom:
27 | fieldRef:
28 | fieldPath: status.podIP
29 | - name: SERVICE_PORT
30 | value: "20880"
31 | ports:
32 | - containerPort: 20880
33 | readinessProbe: # Check whether Stock Service is ready
34 | #tcpSocket: # Wait until TCP port is opened
35 | # port: 20880
36 | # tcpSocket probe will connect and disconnect to 20880 periodically,
37 | # cause massive Dubbo logs: "[DUBBO] disconnected from /10.1.0.1:33994 ..."
38 | exec:
39 | command: ["sh", "-c", "COUNT=`netstat -antp tcp|grep 20880|grep LISTEN -c`; if [ $COUNT -eq 1 ]; then exit 0; else exit 1; fi"]
40 | initialDelaySeconds: 3 # Wait initialDelaySeconds to check the first time
41 | periodSeconds: 5 # Wait periodSeconds to check next time
42 | timeoutSeconds: 1 # Timeout for check process
43 | # initContainers:
44 | # - name: wait-deps
45 | # image: busybox
46 | # imagePullPolicy: IfNotPresent
47 | # 1. Wait PODs of dependencies to be READY.
48 | # 2. Wait services of dependencies to be READY, including service DNS being available.
49 | # command: ['sh', '-c', 'until nslookup pub-nacos; do sleep 3; done;']
--------------------------------------------------------------------------------
/k8s/deployment/svc-user-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: svc-user
5 | spec:
6 | replicas: 1
7 | selector:
8 | matchLabels:
9 | app: svc-user
10 | template:
11 | metadata:
12 | labels:
13 | app: svc-user
14 | version: latest
15 | spec:
16 | containers:
17 | - name: svc-user
18 | image: mydemo/user
19 | imagePullPolicy: IfNotPresent
20 | env:
21 | - name: MYSQL_HOST
22 | value: "mycat-demo.default.svc.cluster.local"
23 | - name: NACOS_HOST
24 | value: "pub-nacos.default.svc.cluster.local"
25 | - name: ZIPKIN_HOST
26 | value: "pub-zipkin.default.svc.cluster.local"
27 | - name: SERVICE_HOST # Use POD IP to register Dubbo service
28 | valueFrom:
29 | fieldRef:
30 | fieldPath: status.podIP
31 | - name: SERVICE_PORT
32 | value: "20880"
33 | ports:
34 | - containerPort: 20880
35 | readinessProbe: # Check whether User Service is ready
36 | #tcpSocket: # Wait until TCP port is opened
37 | # port: 20880
38 | # tcpSocket probe will connect and disconnect to 20880 periodically,
39 | # cause massive Dubbo logs: "[DUBBO] disconnected from /10.1.0.1:33994 ..."
40 | exec:
41 | command: ["sh", "-c", "COUNT=`netstat -antp tcp|grep 20880|grep LISTEN -c`; if [ $COUNT -eq 1 ]; then exit 0; else exit 1; fi"]
42 | initialDelaySeconds: 3 # Wait initialDelaySeconds to check the first time
43 | periodSeconds: 5 # Wait periodSeconds to check next time
44 | timeoutSeconds: 1 # Timeout for check process
45 | # initContainers:
46 | # - name: wait-deps
47 | # image: busybox
48 | # imagePullPolicy: IfNotPresent
49 | # 1. Wait PODs of dependencies to be READY.
50 | # 2. Wait services of dependencies to be READY, including service DNS being available.
51 | # command: ['sh', '-c', 'until nslookup pub-nacos; do sleep 3; done; until nslookup mycat-demo; do sleep 3; done;']
52 |
--------------------------------------------------------------------------------
/k8s/deployment/web-shop-deployment.yaml:
--------------------------------------------------------------------------------
1 | kind: Service
2 | apiVersion: v1
3 | metadata:
4 | name: web-shop
5 | spec:
6 | type: NodePort
7 | ports:
8 | - name: http-shop
9 | port: 8090
10 | targetPort: 8090
11 | nodePort: 30090
12 | selector:
13 | app: web-shop
14 | ---
15 | apiVersion: apps/v1
16 | kind: Deployment
17 | metadata:
18 | name: web-shop
19 | spec:
20 | replicas: 1
21 | selector:
22 | matchLabels:
23 | app: web-shop
24 | template:
25 | metadata:
26 | labels:
27 | app: web-shop
28 | version: latest
29 | spec:
30 | containers:
31 | - name: web-shop
32 | image: mydemo/shopweb
33 | imagePullPolicy: IfNotPresent
34 | env:
35 | - name: NACOS_HOST
36 | value: "pub-nacos.default.svc.cluster.local"
37 | - name: ZIPKIN_HOST
38 | value: "pub-zipkin.default.svc.cluster.local"
39 | ports:
40 | - containerPort: 8090
41 | readinessProbe: # Check whether web-shop is ready
42 | httpGet: # Wait until HTTP status ok
43 | path: /shop
44 | port: 8090
45 | initialDelaySeconds: 3 # Wait initialDelaySeconds to check the first time
46 | periodSeconds: 5 # Wait periodSeconds to check next time
47 | timeoutSeconds: 2 # Timeout for check process
48 | # initContainers:
49 | # - name: wait-deps
50 | # image: busybox
51 | # imagePullPolicy: IfNotPresent
52 | # 1. Wait PODs of dependencies to be READY.
53 | # 2. Wait services of dependencies to be READY, including service DNS being available.
54 | # command: ['sh', '-c', 'until nslookup pub-nacos; do sleep 3; done;']
--------------------------------------------------------------------------------
/k8s/deployment/zipkin-statefulset.yaml:
--------------------------------------------------------------------------------
1 | kind: Service
2 | apiVersion: v1
3 | metadata:
4 | name: pub-zipkin
5 | spec:
6 | type: NodePort # Expose service port to host machine
7 | ports:
8 | - name: http-zipkin
9 | port: 9411
10 | targetPort: 9411
11 | nodePort: 30041 # Expose service port to host machine
12 | selector:
13 | app: pub-zipkin
14 | ---
15 | apiVersion: apps/v1
16 | kind: StatefulSet
17 | metadata:
18 | name: pub-zipkin
19 | spec:
20 | replicas: 1
21 | serviceName: pub-zipkin
22 | selector:
23 | matchLabels:
24 | app: pub-zipkin
25 | template:
26 | metadata:
27 | labels:
28 | app: pub-zipkin
29 | version: 2.19.2
30 | spec:
31 | containers:
32 | - name: pub-zipkin
33 | image: mydemo/zipkin:2.19.2
34 | imagePullPolicy: IfNotPresent
35 | env:
36 | - name: MYSQL_HOST
37 | value: "db-demo.default.svc.cluster.local"
38 | ports:
39 | - containerPort: 9411
40 | readinessProbe: # Check whether ZipKin is ready
41 | httpGet: # Wait until HTTP status ok
42 | path: /zipkin
43 | port: 9411
44 | initialDelaySeconds: 3 # Wait initialDelaySeconds to check the first time
45 | periodSeconds: 5 # Wait periodSeconds to check next time
46 | timeoutSeconds: 2 # Timeout for check process
47 | # initContainers:
48 | # - name: wait-deps
49 | # image: busybox
50 | # imagePullPolicy: IfNotPresent
51 | # 1. Wait PODs of dependencies to be READY.
52 | # 2. Wait services of dependencies to be READY, including service DNS being available.
53 | # command: ['sh', '-c', 'until nslookup db-demo; do sleep 3; done;']
--------------------------------------------------------------------------------
/k8s/install/images.properties:
--------------------------------------------------------------------------------
1 | k8s.gcr.io/pause:3.2=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2
2 | k8s.gcr.io/kube-controller-manager:v1.18.8=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.18.8
3 | k8s.gcr.io/kube-scheduler:v1.18.8=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.18.8
4 | k8s.gcr.io/kube-proxy:v1.18.8=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.18.8
5 | k8s.gcr.io/kube-apiserver:v1.18.8=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.18.8
6 | k8s.gcr.io/etcd:3.4.3-0=registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.3-0
7 | k8s.gcr.io/coredns:1.6.7=registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.6.7
8 | quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1=registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.26.1
9 |
--------------------------------------------------------------------------------
/k8s/install/load_images.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | file="images.properties"
4 | if [ -f "$file" ]
5 | then
6 | echo "$file found."
7 | while IFS='=' read -r key value
8 | do
9 | #echo "${key}=${value}"
10 | docker pull ${value}
11 | docker tag ${value} ${key}
12 | docker rmi ${value}
13 | done < "$file"
14 | else
15 | echo "$file not found."
16 | fi
--------------------------------------------------------------------------------
/k8s/undeploy-k8s.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | kubectl delete Deployment web-shop svc-order svc-user svc-stock svc-item
4 | kubectl delete StatefulSet pub-zipkin pub-nacos mycat-demo db-demo
5 | kubectl delete Service web-shop pub-zipkin pub-nacos mycat-demo db-demo
--------------------------------------------------------------------------------
/order-service/Dockerfile.default:
--------------------------------------------------------------------------------
1 | FROM mydemo/openjdk:8-jre-alpine
2 |
3 | WORKDIR /home
4 | ENV MYSQL_HOST=mysql NACOS_HOST=nacos ZIPKIN_HOST=zipkin SERVICE_PORT=20880
5 | ADD ./target/order-service-0.0.1-SNAPSHOT.jar /home/
6 | EXPOSE 20880
7 | ENTRYPOINT ["java", "-jar", "/home/order-service-0.0.1-SNAPSHOT.jar"]
--------------------------------------------------------------------------------
/order-service/Dockerfile.skywalking:
--------------------------------------------------------------------------------
1 | FROM mydemo/skywalking-base:6.6.0 AS build
2 |
3 | WORKDIR /home/skywalking
4 | RUN rm -rf oap-libs webapp
5 |
6 | FROM mydemo/openjdk:8-jre-alpine
7 |
8 | COPY --from=build /home/skywalking /home/skywalking
9 | ENV MYSQL_HOST=mysql NACOS_HOST=nacos SKYWALKING_HOST=skywalking-oap SKYWALKING_PORT=11800 SERVICE_PORT=20880
10 | ADD ./target/order-service-0.0.1-SNAPSHOT.jar /home/
11 | ADD ./docker-entrypoint.sh /home/
12 | EXPOSE 20880
13 | ENTRYPOINT ["/home/docker-entrypoint.sh", "-javaagent:/home/skywalking/agent/skywalking-agent.jar", "-Dskywalking.agent.service_name=order-svc", "-Dskywalking.collector.backend_service=$SW_AGENT_COLLECTOR_BACKEND_SERVICES", "-jar", "/home/order-service-0.0.1-SNAPSHOT.jar"]
--------------------------------------------------------------------------------
/order-service/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Dockerfile Maven: https://github.com/spotify/dockerfile-maven
4 | # Use shell script to build Docker image because additional process is required in case of SkyWalking enabled
5 |
6 | # The value will be set by package.sh
7 | APM=zipkin
8 |
9 | DIR=`dirname "$0"`
10 | cd $DIR
11 |
12 | if [ "$APM" = "skywalking" ]; then
13 | cp Dockerfile.skywalking Dockerfile
14 | else
15 | cp Dockerfile.default Dockerfile
16 | fi
17 |
18 | docker build -t mydemo/order .
19 | rm -rf Dockerfile
--------------------------------------------------------------------------------
/order-service/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SW_AGENT_COLLECTOR_BACKEND_SERVICES=$SKYWALKING_HOST:$SKYWALKING_PORT
4 |
5 | set -ex
6 | eval java $@
--------------------------------------------------------------------------------
/order-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | my.demo
9 | mydemo-parent
10 | 0.0.1-SNAPSHOT
11 |
12 |
13 | order-service
14 |
15 |
16 | order
17 |
18 |
19 |
20 |
21 |
22 | zipkin
23 |
24 |
25 | &queryInterceptors=brave.mysql8.TracingQueryInterceptor&exceptionInterceptors=brave.mysql8.TracingExceptionInterceptor&zipkinServiceName=db-${application.name}
26 |
27 |
28 |
29 | seata
30 |
31 |
32 | io.seata
33 | seata-spring-boot-starter
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | src/main/resources
43 | true
44 |
45 | application.yml
46 | logback.xml
47 | mappers/*.xml
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | my.demo
56 | service-client
57 | 0.0.1-SNAPSHOT
58 |
59 |
60 | org.springframework.boot
61 | spring-boot-starter
62 |
63 |
64 | org.springframework
65 | spring-tx
66 |
67 |
68 | org.mybatis.spring.boot
69 | mybatis-spring-boot-starter
70 |
71 |
72 | org.mybatis
73 | mybatis
74 |
75 |
76 | mysql
77 | mysql-connector-java
78 |
79 |
80 | com.alibaba
81 | druid
82 |
83 |
84 |
85 | io.zipkin.brave
86 | brave-instrumentation-mysql8
87 |
88 |
89 |
--------------------------------------------------------------------------------
/order-service/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # The value will be set by package.sh
4 | MYSQL_HOST=mysql
5 | docker run -d --net=mydemo --name order -e SERVICE_HOST=order -e MYSQL_HOST=$MYSQL_HOST -e NACOS_HOST=nacos -e ZIPKIN_HOST=zipkin -e SKYWALKING_HOST=skywalking-oap mydemo/order
--------------------------------------------------------------------------------
/order-service/src/main/java/my/demo/dao/order/OrderDao.java:
--------------------------------------------------------------------------------
1 | package my.demo.dao.order;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import org.apache.ibatis.annotations.Insert;
7 | import org.apache.ibatis.annotations.Mapper;
8 | import org.apache.ibatis.annotations.Param;
9 | import org.apache.ibatis.annotations.ResultMap;
10 | import org.apache.ibatis.annotations.ResultType;
11 | import org.apache.ibatis.annotations.Select;
12 | import org.apache.ibatis.annotations.Update;
13 |
14 | import my.demo.entity.Order;
15 | import my.demo.entity.OrderItem;
16 |
17 | @Mapper
18 | public interface OrderDao {
19 | @Insert("insert into ord_order (order_id, user_id, status, total, discount, payment, pay_time, pay_status, contact, phone, address, created_at) "
20 | + "values(#{orderId}, #{userId}, #{status}, #{total}, #{discount}, #{payment}, #{payTime}, #{payStatus}, #{contact}, #{phone}, #{address}, #{createdAt})")
21 | int createOrder(Order order);
22 |
23 | @Insert("insert into ord_order_item (order_id, item_id, title, quantity, price, subtotal, discount, created_at) "
24 | + "values(#{orderId}, #{itemId}, #{title}, #{quantity}, #{price}, #{subtotal}, #{discount}, #{createdAt})")
25 | int createOrderItem(OrderItem orderItem);
26 |
27 | @Update("update ord_order_item set subtotal=subtotal-2, discount=discount+2 where order_id=#{orderId}")
28 | int testUpdateOrderItem(@Param("orderId") long orderId);
29 |
30 | ArrayList findOrders(@Param("orderIds") List orderIds);
31 |
32 | @Select("select * from ord_order where order_id = #{orderId}")
33 | @ResultMap("order")
34 | Order getOrder(long orderId);
35 |
36 | @Select("select * from ord_order_item where order_id = #{orderId}")
37 | @ResultMap("orderItem")
38 | ArrayList getOrderItems(long orderId);
39 |
40 | @Insert("insert into ord_user_order (user_id, order_id) values(#{userId}, #{orderId})")
41 | int createUserOrder(@Param("userId") long userId, @Param("orderId") long orderId);
42 | @Select("select order_id from ord_user_order where user_id = #{userId} limit #{offset}, #{count}")
43 | @ResultType(Long.class)
44 | List findUserOrderIds(@Param("userId") long userId, @Param("offset") int offset, @Param("count") int count);
45 | }
--------------------------------------------------------------------------------
/order-service/src/main/java/my/demo/service/order/Application.java:
--------------------------------------------------------------------------------
1 | package my.demo.service.order;
2 |
3 | import org.mybatis.spring.annotation.MapperScan;
4 | import org.springframework.boot.WebApplicationType;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.boot.builder.SpringApplicationBuilder;
7 |
8 | import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
9 |
10 | @SpringBootApplication(scanBasePackages = { "my.demo.service.order", "my.demo.utils" })
11 | @MapperScan(basePackages = { "my.demo.dao.order" })
12 | @EnableDubbo(scanBasePackages = { "my.demo.service.order" })
13 | public class Application {
14 | public static void main(String[] args) {
15 | new SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE).run(args);
16 | }
17 | }
--------------------------------------------------------------------------------
/order-service/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | UTF-8
15 | ${CONSOLE_LOG_PATTERN:-%clr([%d{${LOG_DATEFORMAT_PATTERN:-yyMMdd HH:mm:ss.SSS}}]){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%-35.35logger{35}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
16 |
17 |
18 |
19 |
20 | UTF-8
21 |
22 | ${CONSOLE_LOG_PATTERN:-%clr([%d{${LOG_DATEFORMAT_PATTERN:-yyMMdd HH:mm:ss.SSS}}]){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} ${log.traceInfo}%clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/order-service/src/main/resources/mappers/OrderMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | select * from ord_order where order_id in #{id}
34 |
35 |
--------------------------------------------------------------------------------
/package.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | PROJECT_HOME=`dirname "$0"`
4 |
5 | show_usage() {
6 | echo " Run \"mvn clean package spring-boot:repackage -P profiles\" for all services and shop-app application."
7 | echo " Usage:"
8 | echo " 1. Options to enable database sharding:"
9 | echo " -mycat"
10 | echo " -sharding-proxy"
11 | echo " 2. Options to enable global transaction management:"
12 | echo " -seata"
13 | echo " 3. Options to enable APM tools:"
14 | echo " -skywalking"
15 | echo " -pinpoint"
16 | echo " -zipkin"
17 | }
18 | package_project() {
19 | cd $1
20 | mvn $CLEAN package spring-boot:repackage "$PROFILES"
21 | cd ..
22 | }
23 |
24 | if [ $# -eq 0 ]; then
25 | show_usage
26 | sleep 1
27 | fi;
28 |
29 | PROFILES="-P dev"
30 | DB_HOST="mysql"
31 | APM=""
32 | CLEAN=""
33 |
34 | while [ -n "$1" ]
35 | do
36 | case "$1" in
37 | -mycat|--mycat)
38 | PROFILES="$PROFILES,mycat";
39 | DB_HOST="mycat"
40 | shift 1;;
41 | -shardingproxy|--shardingproxy)
42 | PROFILES="$PROFILES,shardingproxy";
43 | DB_HOST="shardingproxy"
44 | shift 1;;
45 | -seata|--seata) PROFILES="$PROFILES,seata"; shift 1;;
46 | -zipkin|--zipkin)
47 | PROFILES="$PROFILES,zipkin";
48 | APM="zipkin"
49 | shift 1;;
50 | -skywalking|--skywalking)
51 | PROFILES="$PROFILES,skywalking";
52 | APM="skywalking"
53 | shift 1;;
54 | -pinpoint|--pinpoint)
55 | PROFILES="$PROFILES,pinpoint";
56 | APM="pinpoint"
57 | shift 1;;
58 | -clean|--clean) CLEAN="clean"; shift 1;;
59 | ?|-?|-help|--help) show_usage; exit 0;;
60 | --) break;;
61 | *) echo " Invalid parameter: $1"; exit 1;;
62 | esac
63 | done
64 |
65 | cd $PROJECT_HOME
66 | mvn install
67 | cd service-client
68 | mvn clean install
69 | cd ..
70 |
71 | package_project "item-service"
72 | package_project "stock-service"
73 | package_project "user-service"
74 | package_project "order-service"
75 | package_project "shop-web"
76 |
77 | SED="sed"
78 | if [ `uname` == "Darwin" ]; then
79 | SED="gsed"
80 | fi
81 | # order和user服务需要连接数据库:
82 | # 1. 本地运行模式:通过maven的profile完成数据库HOST、PORT配置;
83 | # 2. Docker容器运行:通过docker run传递环境变量,将数据库HOST、PORT传递到容器;
84 | $SED -i "s/^MYSQL_HOST=.*$/MYSQL_HOST=$DB_HOST/g" order-service/run.sh
85 | $SED -i "s/^MYSQL_HOST=.*$/MYSQL_HOST=$DB_HOST/g" user-service/run.sh
86 | # 3. K8s运行:修改通过yaml文件指定HOST、PORT
87 | $SED -i "s/(db|mycat)-mydemo/$DB_HOST/g" k8s/deployment/svc-user-deployment.yaml
88 | $SED -i "s/(db|mycat)-mydemo/$DB_HOST/g" k8s/deployment/svc-order-deployment.yaml
89 | # APM使用zipkin和skywalking时,Docker容器构建方法不一样,这里为Docker容器构建进行参数设置
90 | $SED -i "s/^APM=.*$/APM=$APM/g" item-service/build.sh
91 | $SED -i "s/^APM=.*$/APM=$APM/g" stock-service/build.sh
92 | $SED -i "s/^APM=.*$/APM=$APM/g" user-service/build.sh
93 | $SED -i "s/^APM=.*$/APM=$APM/g" order-service/build.sh
94 | $SED -i "s/^APM=.*$/APM=$APM/g" shop-web/build.sh
95 |
96 | echo " Finished"
97 |
--------------------------------------------------------------------------------
/postman/README.md:
--------------------------------------------------------------------------------
1 | ### Postman + Newman for Test Automation
2 | Use `Postman` to build tests:
3 | 
4 |
5 | `newman` is a command line tool for running `Postman` tests in shell, it can work with Jenkins:
6 | 
7 |
8 | `xmysql` is used for `newman` to clear data in `MySQL` before running tests.
9 |
--------------------------------------------------------------------------------
/postman/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cd `dirname $0`
4 | HOME=`pwd`
5 | cd nodejs
6 | docker build -t mydemo/nodejs:10 .
7 |
8 | cd ../xmysql
9 | docker build -t mydemo/xmysql:0.4.9 .
10 |
11 | cd ../newman
12 | docker build -t mydemo/newman:4.6.0 .
--------------------------------------------------------------------------------
/postman/newman/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mydemo/nodejs:10
2 |
3 | RUN cnpm install -g newman@4.6.0
4 |
5 | VOLUME /etc/newman
6 | WORKDIR /etc/newman
7 | #ENTRYPOINT [ "newman" ]
--------------------------------------------------------------------------------
/postman/newman/docker-env.postman_environment.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "09f63dc2-84d0-413d-88c5-59ab9820f495",
3 | "name": "docker-env",
4 | "values": [
5 | {
6 | "key": "xmysql",
7 | "value": "xmysql:3000",
8 | "enabled": true
9 | },
10 | {
11 | "key": "shopweb",
12 | "value": "shopweb:8090",
13 | "enabled": true
14 | }
15 | ],
16 | "_postman_variable_scope": "environment",
17 | "_postman_exported_at": "2020-03-15T06:38:49.367Z",
18 | "_postman_exported_using": "Postman/7.20.1"
19 | }
--------------------------------------------------------------------------------
/postman/newman/k8s-env.postman_environment.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "ec55be7b-5264-4c54-840f-85dceddde70a",
3 | "name": "k8s-env",
4 | "values": [
5 | {
6 | "key": "xmysql",
7 | "value": "test-xmysql.default.svc.cluster.local:3000",
8 | "enabled": true
9 | },
10 | {
11 | "key": "shopweb",
12 | "value": "web-shop.default.svc.cluster.local:8090",
13 | "enabled": true
14 | }
15 | ],
16 | "_postman_variable_scope": "environment",
17 | "_postman_exported_at": "2020-03-15T06:38:58.547Z",
18 | "_postman_exported_using": "Postman/7.20.1"
19 | }
--------------------------------------------------------------------------------
/postman/newman/local-env.postman_environment.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "1d800264-539b-487c-a8d7-2bd96766261e",
3 | "name": "local-env",
4 | "values": [
5 | {
6 | "key": "xmysql",
7 | "value": "localhost:13000",
8 | "enabled": true
9 | },
10 | {
11 | "key": "shopweb",
12 | "value": "localhost:18090",
13 | "enabled": true
14 | }
15 | ],
16 | "_postman_variable_scope": "environment",
17 | "_postman_exported_at": "2020-03-15T06:39:02.342Z",
18 | "_postman_exported_using": "Postman/7.20.1"
19 | }
--------------------------------------------------------------------------------
/postman/nodejs/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:10-alpine
2 |
3 | # Use cnpm to improve network speed in China
4 | RUN npm install -g cnpm --registry=https://registry.npm.taobao.org
--------------------------------------------------------------------------------
/postman/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cd `dirname $0`
4 | HOME=`pwd`
5 |
6 | docker run -d --net=mydemo --name xmysql mydemo/xmysql:0.4.9
7 |
8 | #NEWMAN_HOME="/Users/richie-home/Documents/workspace/my-demo/postman/newman"
9 | NEWMAN_HOME="F:\workspace\mydemo\postman\newman"
10 | docker run --net=mydemo --name newman -v "$NEWMAN_HOME:/etc/newman" -it mydemo/newman:4.6.0 newman run mydemo.postman_collection.json -e docker-env.postman_environment.json --reporters cli,json --reporter-json-export mydemo-report.json
11 |
12 | docker stop xmysql
13 | docker rm xmysql newman
14 |
--------------------------------------------------------------------------------
/postman/xmysql/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mydemo/nodejs:10
2 |
3 | RUN cnpm install -g xmysql
4 |
5 | ENV MYSQL_HOST=mysql MYSQL_PORT=3306 MYSQL_USER=mydemo MYSQL_PSW=mydemo DB=mydemo-dn1
6 | ADD entrypoint.sh /home/
7 | ENTRYPOINT [ "sh", "-c", "/home/entrypoint.sh" ]
--------------------------------------------------------------------------------
/postman/xmysql/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # If -r is not specified, xmysql will listen on 127.0.0.1, it's not accessable outside the container.
4 | xmysql -h $MYSQL_HOST -o $MYSQL_PORT -u $MYSQL_USER -p $MYSQL_PSW -d $DB -r 0.0.0.0
--------------------------------------------------------------------------------
/selenium/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | my.demo
8 | selenium-demo
9 | 0.0.1-SNAPSHOT
10 |
11 |
12 |
13 |
14 | src/main/resources
15 | true
16 |
17 | application.yml
18 | logback.xml
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | junit
27 | junit
28 | 4.13.1
29 |
30 |
31 | org.seleniumhq.selenium
32 | selenium-java
33 | 3.141.59
34 |
35 |
36 | org.seleniumhq.selenium
37 | selenium-edge-driver
38 |
39 |
40 | org.seleniumhq.selenium
41 | selenium-firefox-driver
42 |
43 |
44 | org.seleniumhq.selenium
45 | selenium-ie-driver
46 |
47 |
48 | org.seleniumhq.selenium
49 | selenium-opera-driver
50 |
51 |
52 | org.seleniumhq.selenium
53 | selenium-safari-driver
54 |
55 |
56 |
57 |
61 |
62 |
73 |
74 |
--------------------------------------------------------------------------------
/service-client/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | my.demo
9 | mydemo-parent
10 | 0.0.1-SNAPSHOT
11 |
12 |
13 | service-client
14 |
15 |
16 |
17 | org.springframework.boot
18 | spring-boot-starter
19 | provided
20 |
21 |
22 | org.springframework
23 | spring-tx
24 | provided
25 |
26 |
27 | com.fasterxml.jackson.core
28 | jackson-annotations
29 | provided
30 |
31 |
32 | org.mybatis.spring.boot
33 | mybatis-spring-boot-starter
34 | provided
35 |
36 |
37 | io.seata
38 | seata-spring-boot-starter
39 | provided
40 |
41 |
42 |
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/entity/Cart.java:
--------------------------------------------------------------------------------
1 | package my.demo.entity;
2 |
3 | import java.io.Serializable;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | public class Cart implements Serializable {
8 | private static final long serialVersionUID = -1531734075915913410L;
9 | private long userId;
10 | private String contact;
11 | private String phone;
12 | private String address;
13 | private List items;
14 |
15 | public Cart(long userId) {
16 | this.userId = userId;
17 | this.items = new ArrayList<>();
18 | }
19 | public Cart saveAddress(String contact, String phone, String address) {
20 | this.contact = contact;
21 | this.phone = phone;
22 | this.address = address;
23 | return this;
24 | }
25 | public Cart addItem(int itemId, int quantity, double price, double discount) {
26 | CartItem ci = new CartItem();
27 | ci.setItemId(itemId);
28 | ci.setQuantity(quantity);
29 | ci.setPrice(price);
30 | ci.setDiscount(discount);
31 | ci.setSubtotal(quantity * price - discount);
32 | this.items.add(ci);
33 | return this;
34 | }
35 |
36 | public long getUserId() {
37 | return userId;
38 | }
39 | public void setUserId(long userId) {
40 | this.userId = userId;
41 | }
42 | public String getContact() {
43 | return contact;
44 | }
45 | public void setContact(String contact) {
46 | this.contact = contact;
47 | }
48 | public String getPhone() {
49 | return phone;
50 | }
51 | public void setPhone(String phone) {
52 | this.phone = phone;
53 | }
54 | public String getAddress() {
55 | return address;
56 | }
57 | public void setAddress(String address) {
58 | this.address = address;
59 | }
60 | public List getItems() {
61 | return items;
62 | }
63 | public void setItems(List items) {
64 | this.items = items;
65 | }
66 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/entity/CartItem.java:
--------------------------------------------------------------------------------
1 | package my.demo.entity;
2 |
3 | import java.io.Serializable;
4 |
5 | public class CartItem implements Serializable {
6 | private static final long serialVersionUID = -3350171720912880246L;
7 | private int itemId;
8 | private int quantity;
9 | private double price;
10 | private double subtotal;
11 | private double discount;
12 |
13 | public int getItemId() {
14 | return itemId;
15 | }
16 | public void setItemId(int productId) {
17 | this.itemId = productId;
18 | }
19 | public int getQuantity() {
20 | return quantity;
21 | }
22 | public void setQuantity(int quantity) {
23 | this.quantity = quantity;
24 | }
25 | public double getPrice() {
26 | return price;
27 | }
28 | public void setPrice(double price) {
29 | this.price = price;
30 | }
31 | public double getSubtotal() {
32 | return subtotal;
33 | }
34 | public void setSubtotal(double subtotal) {
35 | this.subtotal = subtotal;
36 | }
37 | public double getDiscount() {
38 | return discount;
39 | }
40 | public void setDiscount(double discount) {
41 | this.discount = discount;
42 | }
43 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/entity/Item.java:
--------------------------------------------------------------------------------
1 | package my.demo.entity;
2 |
3 | import java.io.Serializable;
4 |
5 | public class Item implements Serializable {
6 | private static final long serialVersionUID = -7845145044315043115L;
7 | private int id;
8 | private String title;
9 | private double price;
10 |
11 | public int getId() {
12 | return id;
13 | }
14 | public void setId(int id) {
15 | this.id = id;
16 | }
17 | public String getTitle() {
18 | return title;
19 | }
20 | public void setTitle(String title) {
21 | this.title = title;
22 | }
23 | public double getPrice() {
24 | return price;
25 | }
26 | public void setPrice(double price) {
27 | this.price = price;
28 | }
29 |
30 | @Override
31 | public boolean equals(Object obj) {
32 | if(obj==null) return false;
33 | if(this==obj) return true;
34 | if(this.getClass()!=obj.getClass()) return false;
35 | return this.id == ((Item)obj).id;
36 | }
37 | @Override
38 | public int hashCode() {
39 | return this.id;
40 | }
41 | @Override
42 | public String toString() {
43 | return this.id + "-" + this.title;
44 | }
45 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/entity/OrderItem.java:
--------------------------------------------------------------------------------
1 | package my.demo.entity;
2 |
3 | import java.io.Serializable;
4 | import java.util.Date;
5 |
6 | import com.fasterxml.jackson.annotation.JsonAutoDetect;
7 | import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
8 | import com.fasterxml.jackson.annotation.JsonFormat;
9 |
10 | @JsonAutoDetect(getterVisibility=Visibility.NONE, setterVisibility=Visibility.NONE, fieldVisibility=Visibility.ANY)
11 | public class OrderItem implements Serializable {
12 | private static final long serialVersionUID = 7609913567717327072L;
13 | private long orderItemId;
14 | private long orderId;
15 | private int itemId;
16 | private String title;
17 | private int quantity;
18 | private double price;
19 | private double subtotal;
20 | private double discount;
21 | @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSS", timezone="Asia/Shanghai")
22 | private Date createdAt;
23 | @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSS", timezone="Asia/Shanghai")
24 | private Date lastUpdate;
25 |
26 | public long getOrderItemId() {
27 | return orderItemId;
28 | }
29 | public void setOrderItemId(long detailId) {
30 | this.orderItemId = detailId;
31 | }
32 | public long getOrderId() {
33 | return orderId;
34 | }
35 | public void setOrderId(long orderId) {
36 | this.orderId = orderId;
37 | }
38 | public int getItemId() {
39 | return itemId;
40 | }
41 | public void setItemId(int itemId) {
42 | this.itemId = itemId;
43 | }
44 | public String getTitle() {
45 | return title;
46 | }
47 | public void setTitle(String title) {
48 | this.title = title;
49 | }
50 | public int getQuantity() {
51 | return quantity;
52 | }
53 | public void setQuantity(int quantity) {
54 | this.quantity = quantity;
55 | }
56 | public double getPrice() {
57 | return price;
58 | }
59 | public void setPrice(double price) {
60 | this.price = price;
61 | }
62 | public double getSubtotal() {
63 | return subtotal;
64 | }
65 | public void setSubtotal(double subtotal) {
66 | this.subtotal = subtotal;
67 | }
68 | public double getDiscount() {
69 | return discount;
70 | }
71 | public void setDiscount(double discount) {
72 | this.discount = discount;
73 | }
74 | public Date getCreatedAt() {
75 | return createdAt;
76 | }
77 | public void setCreatedAt(Date createdAt) {
78 | this.createdAt = createdAt;
79 | }
80 | public Date getLastUpdate() {
81 | return lastUpdate;
82 | }
83 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/entity/Stock.java:
--------------------------------------------------------------------------------
1 | package my.demo.entity;
2 |
3 | import java.io.Serializable;
4 |
5 | public class Stock implements Serializable {
6 | private static final long serialVersionUID = -4603287294441831684L;
7 | private int itemId;
8 | private int totalQty;
9 | private int lockQty;
10 |
11 | public int getItemId() {
12 | return itemId;
13 | }
14 | public void setItemId(int itemId) {
15 | this.itemId = itemId;
16 | }
17 | public int getTotalQty() {
18 | return totalQty;
19 | }
20 | public void setTotalQty(int totalQty) {
21 | this.totalQty = totalQty;
22 | }
23 | public int getLockQty() {
24 | return lockQty;
25 | }
26 | public void setLockQty(int lockQty) {
27 | this.lockQty = lockQty;
28 | }
29 | public int getAvailableQty() {
30 | return this.totalQty - this.lockQty;
31 | }
32 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/entity/User.java:
--------------------------------------------------------------------------------
1 | package my.demo.entity;
2 |
3 | import java.io.Serializable;
4 | import java.util.Date;
5 |
6 | import com.fasterxml.jackson.annotation.JsonAutoDetect;
7 | import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
8 | import com.fasterxml.jackson.annotation.JsonFormat;
9 |
10 | @JsonAutoDetect(getterVisibility=Visibility.NONE, setterVisibility=Visibility.NONE, fieldVisibility=Visibility.ANY)
11 | public class User implements Serializable {
12 | private static final long serialVersionUID = -5284692770015499256L;
13 | private long userId;
14 | private String nickname;
15 | private String mobile;
16 | private String email;
17 | @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSS", timezone="Asia/Shanghai")
18 | private Date createdAt;
19 | @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSS", timezone="Asia/Shanghai")
20 | private Date lastUpdate;
21 |
22 | public long getUserId() {
23 | return userId;
24 | }
25 | public void setUserId(long userId) {
26 | this.userId = userId;
27 | }
28 | public String getNickname() {
29 | return nickname;
30 | }
31 | public void setNickname(String nickname) {
32 | this.nickname = nickname==null ? "" : nickname;
33 | }
34 | public String getMobile() {
35 | return mobile;
36 | }
37 | public void setMobile(String mobile) {
38 | this.mobile = mobile==null ? "" : mobile;
39 | }
40 | public String getEmail() {
41 | return email;
42 | }
43 | public void setEmail(String email) {
44 | this.email = email==null ? "" : email;
45 | }
46 | public Date getCreatedAt() {
47 | return createdAt;
48 | }
49 | public void setCreatedAt(Date createdAt) {
50 | this.createdAt = createdAt==null ? new Date() : createdAt;
51 | }
52 | public Date getLastUpdate() {
53 | return lastUpdate;
54 | }
55 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/entity/UserAccount.java:
--------------------------------------------------------------------------------
1 | package my.demo.entity;
2 |
3 | import java.io.Serializable;
4 |
5 | public class UserAccount implements Serializable {
6 | private static final long serialVersionUID = 8639953921479963556L;
7 | private String account;
8 | private String password;
9 | private long userId;
10 | private int accountHash;
11 |
12 | public String getAccount() {
13 | return account;
14 | }
15 | public void setAccount(String account) {
16 | this.account = account;
17 | }
18 | public String getPassword() {
19 | return password;
20 | }
21 | public void setPassword(String password) {
22 | this.password = password;
23 | }
24 | public long getUserId() {
25 | return userId;
26 | }
27 | public void setUserId(long userId) {
28 | this.userId = userId;
29 | }
30 | public int getAccountHash() {
31 | return accountHash;
32 | }
33 | public void setAccountHash(int accountHash) {
34 | this.accountHash = accountHash;
35 | }
36 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/service/HelloService.java:
--------------------------------------------------------------------------------
1 | package my.demo.service;
2 |
3 | public interface HelloService {
4 | String hello(String name);
5 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/service/ItemService.java:
--------------------------------------------------------------------------------
1 | package my.demo.service;
2 |
3 | import java.util.ArrayList;
4 |
5 | import my.demo.entity.Item;
6 |
7 | public interface ItemService {
8 | ServiceResult- getItem(int itemId);
9 | ServiceResult
> findItem();
10 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/service/OrderService.java:
--------------------------------------------------------------------------------
1 | package my.demo.service;
2 |
3 | import java.util.ArrayList;
4 |
5 | import my.demo.entity.Cart;
6 | import my.demo.entity.Order;
7 | import my.demo.entity.OrderItem;
8 |
9 | public interface OrderService {
10 | ServiceResult createOrder(Cart cart);
11 | ServiceResult> findUserOrders(long userId, int offset, int count);
12 | ServiceResult> getOrderItems(long orderId);
13 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/service/ServiceResult.java:
--------------------------------------------------------------------------------
1 | package my.demo.service;
2 |
3 | import java.io.Serializable;
4 |
5 | public class ServiceResult implements Serializable {
6 | private static final long serialVersionUID = -8163829609385722989L;
7 | private T result = null;
8 | private boolean success = true;
9 | private String message = "";
10 |
11 | public ServiceResult() {
12 |
13 | }
14 | public ServiceResult(T result) {
15 | this.result = result;
16 | this.success = true;
17 | }
18 | public ServiceResult fail(String message) {
19 | this.success = false;
20 | this.message = message;
21 | return this;
22 | }
23 | public ServiceResult success(T result) {
24 | this.success = true;
25 | this.result = result;
26 | return this;
27 | }
28 |
29 | public T getResult() {
30 | return result;
31 | }
32 | public void setResult(T result) {
33 | this.result = result;
34 | }
35 | public boolean isSuccess() {
36 | return success;
37 | }
38 | public void setSuccess(boolean success) {
39 | this.success = success;
40 | }
41 | public String getMessage() {
42 | return message;
43 | }
44 | public void setMessage(String message) {
45 | this.message = message;
46 | }
47 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/service/StockService.java:
--------------------------------------------------------------------------------
1 | package my.demo.service;
2 |
3 | import my.demo.entity.Stock;
4 |
5 | public interface StockService {
6 | ServiceResult getStock(int itemId);
7 | ServiceResult lock(int itemId, int lockQty);
8 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/service/UserService.java:
--------------------------------------------------------------------------------
1 | package my.demo.service;
2 |
3 | import my.demo.entity.User;
4 |
5 | public interface UserService {
6 | ServiceResult registerByMobile(String mobile, String password);
7 | ServiceResult login(String account, String password);
8 | ServiceResult getUser(long userId);
9 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/utils/MyDemoUtils.java:
--------------------------------------------------------------------------------
1 | package my.demo.utils;
2 |
3 | import java.net.InetAddress;
4 | import java.net.UnknownHostException;
5 |
6 | import org.apache.skywalking.apm.toolkit.trace.ActiveSpan;
7 | import org.springframework.util.ClassUtils;
8 |
9 | import io.seata.core.context.RootContext;
10 |
11 | public class MyDemoUtils {
12 | private static boolean skywalkingPresent = ClassUtils.isPresent("org.apache.skywalking.apm.toolkit.trace.ActiveSpan", ClassUtils.getDefaultClassLoader());
13 | private static boolean seataPresent = ClassUtils.isPresent("io.seata.core.context.RootContext", ClassUtils.getDefaultClassLoader());
14 |
15 | private MyDemoUtils() {}
16 | /**
17 | * Add a user defined tag in current span if SkyWalking is enabled
18 | * @param name
19 | * @param value
20 | */
21 | public static void tag(String name, Object value) {
22 | if(skywalkingPresent) {
23 | if(value==null) ActiveSpan.tag(name, "null");
24 | else ActiveSpan.tag(name, value.toString());
25 | }
26 | }
27 |
28 | public static boolean isSeataPresent() {
29 | return seataPresent;
30 | }
31 | /**
32 | * XID: Seata global transaction ID
33 | * @return
34 | */
35 | public static String getXID() {
36 | return RootContext.getXID();
37 | }
38 |
39 | public static String getIpByHostName(String hostName) {
40 | InetAddress addr = null;
41 | if(hostName!=null && !hostName.isEmpty() && !"localhost".equalsIgnoreCase(hostName.trim())) {
42 | try {
43 | addr = InetAddress.getByName(hostName);
44 | return addr.getHostAddress();
45 | } catch (UnknownHostException e) {
46 | e.printStackTrace();
47 | }
48 | }
49 | try {
50 | addr = InetAddress.getLocalHost();
51 | return addr.getHostAddress();
52 | } catch (UnknownHostException e) {
53 | return "";
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/utils/SeataConfiguration.java:
--------------------------------------------------------------------------------
1 | package my.demo.utils;
2 |
3 | import org.apache.ibatis.session.SqlSessionFactory;
4 | import org.mybatis.spring.SqlSessionFactoryBean;
5 | import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
6 | import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.beans.factory.annotation.Value;
11 | import org.springframework.boot.autoconfigure.AutoConfigureAfter;
12 | import org.springframework.boot.autoconfigure.AutoConfigureBefore;
13 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
14 | import org.springframework.context.annotation.Bean;
15 | import org.springframework.context.annotation.Configuration;
16 | import org.springframework.context.annotation.Primary;
17 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
18 | import org.springframework.jdbc.datasource.DataSourceTransactionManager;
19 | import org.springframework.transaction.TransactionManager;
20 | import org.springframework.transaction.annotation.EnableTransactionManagement;
21 | import org.springframework.transaction.annotation.TransactionManagementConfigurer;
22 |
23 | import com.alibaba.druid.pool.DruidDataSource;
24 |
25 | import io.seata.rm.datasource.DataSourceProxy;
26 |
27 | @Configuration
28 | @ConditionalOnClass({ DataSourceProxy.class, SqlSessionFactory.class })
29 | @AutoConfigureBefore(MybatisAutoConfiguration.class)
30 | @AutoConfigureAfter(DruidConfiguration.class)
31 | @EnableTransactionManagement
32 | public class SeataConfiguration implements TransactionManagementConfigurer {
33 | Logger log = LoggerFactory.getLogger(this.getClass());
34 |
35 | @Value("${mybatis.mapperLocations}")
36 | String mapperLocations;
37 | @Autowired
38 | DruidDataSource druidDataSource;
39 |
40 | @Bean
41 | public DataSourceProxy dataSourceProxy(DruidDataSource druidDataSource){
42 | return new DataSourceProxy(druidDataSource);
43 | }
44 | @Bean
45 | @Primary
46 | public DataSourceTransactionManager transactionManager(DataSourceProxy dataSourceProxy) {
47 | return new DataSourceTransactionManager(dataSourceProxy);
48 | }
49 | @Bean
50 | public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy) throws Exception {
51 | log.info("[seata-configuration] Mybatis sqlSessionFactory created, mapperLocations: {}", mapperLocations);
52 | SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
53 | factoryBean.setDataSource(dataSourceProxy);
54 | factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
55 | factoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
56 | return factoryBean.getObject();
57 | }
58 |
59 | @Override
60 | public TransactionManager annotationDrivenTransactionManager() {
61 | return transactionManager(dataSourceProxy(druidDataSource));
62 | }
63 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/utils/ZipkinConfiguration.java:
--------------------------------------------------------------------------------
1 | package my.demo.utils;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
6 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 |
10 | import brave.Tracing;
11 | import brave.context.slf4j.MDCScopeDecorator;
12 | import brave.dubbo.rpc.TracingFilter;
13 | import brave.propagation.B3Propagation;
14 | import brave.propagation.ExtraFieldPropagation;
15 | import brave.propagation.ThreadLocalCurrentTraceContext;
16 | import brave.sampler.Sampler;
17 | import zipkin2.Span;
18 | import zipkin2.reporter.AsyncReporter;
19 | import zipkin2.reporter.Sender;
20 | import zipkin2.reporter.okhttp3.OkHttpSender;
21 |
22 | @Configuration
23 | @EnableConfigurationProperties({ZipkinProperties.class})
24 | @ConditionalOnClass(TracingFilter.class)
25 | public class ZipkinConfiguration {
26 | @Bean
27 | public Tracing tracing(ZipkinProperties properties) {
28 | Sender sender = OkHttpSender.create(properties.getServer());
29 | AsyncReporter reporter = AsyncReporter.builder(sender)
30 | .closeTimeout(properties.getConnectTimeout(), TimeUnit.MILLISECONDS)
31 | .messageTimeout(properties.getReadTimeout(), TimeUnit.MILLISECONDS)
32 | .build();
33 | return Tracing.newBuilder()
34 | .localServiceName(properties.getServiceName())
35 | .propagationFactory(ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "brave-trace"))
36 | .sampler(Sampler.ALWAYS_SAMPLE)
37 | .spanReporter(reporter)
38 | .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder().addScopeDecorator(MDCScopeDecorator.create()).build())
39 | .build();
40 | }
41 | }
--------------------------------------------------------------------------------
/service-client/src/main/java/my/demo/utils/ZipkinProperties.java:
--------------------------------------------------------------------------------
1 | package my.demo.utils;
2 |
3 | import org.springframework.beans.factory.annotation.Value;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 |
6 | @ConfigurationProperties(prefix="zipkin")
7 | public class ZipkinProperties {
8 | @Value("${dubbo.application.name}")
9 | private String serviceName;
10 | private String server;
11 | private int connectTimeout;
12 | private int readTimeout;
13 |
14 | public String getServiceName() {
15 | return serviceName;
16 | }
17 | public void setServiceName(String serviceName) {
18 | this.serviceName = serviceName;
19 | }
20 | public String getServer() {
21 | return server;
22 | }
23 | public void setServer(String httpUrl) {
24 | this.server = httpUrl;
25 | }
26 | public int getConnectTimeout() {
27 | return connectTimeout;
28 | }
29 | public void setConnectTimeout(int httpConnectTimeout) {
30 | this.connectTimeout = httpConnectTimeout;
31 | }
32 | public int getReadTimeout() {
33 | return readTimeout;
34 | }
35 | public void setReadTimeout(int httpReadTimeout) {
36 | this.readTimeout = httpReadTimeout;
37 | }
38 | }
--------------------------------------------------------------------------------
/shop-web/Dockerfile.default:
--------------------------------------------------------------------------------
1 | FROM mydemo/openjdk:8-jre-alpine
2 |
3 | WORKDIR /home
4 | ENV NACOS_HOST=nacos ZIPKIN_HOST=zipkin SERVICE_PORT=8090
5 | ADD ./target/shop-web-0.0.1-SNAPSHOT.jar /home/
6 | EXPOSE 8090
7 | ENTRYPOINT ["java", "-jar", "/home/shop-web-0.0.1-SNAPSHOT.jar"]
--------------------------------------------------------------------------------
/shop-web/Dockerfile.skywalking:
--------------------------------------------------------------------------------
1 | FROM mydemo/skywalking-base:6.6.0 AS build
2 |
3 | WORKDIR /home/skywalking
4 | RUN rm -rf oap-libs webapp
5 |
6 | FROM mydemo/openjdk:8-jre-alpine
7 |
8 | COPY --from=build /home/skywalking /home/skywalking
9 | ENV NACOS_HOST=nacos SKYWALKING_HOST=skywalking-oap SKYWALKING_PORT=11800 SERVICE_PORT=8090
10 | ADD ./target/shop-web-0.0.1-SNAPSHOT.jar /home/
11 | ADD ./docker-entrypoint.sh /home/
12 | EXPOSE 8090
13 | ENTRYPOINT ["/home/docker-entrypoint.sh", "-javaagent:/home/skywalking/agent/skywalking-agent.jar", "-Dskywalking.agent.service_name=shop-web", "-Dskywalking.collector.backend_service=$SW_AGENT_COLLECTOR_BACKEND_SERVICES", "-jar", "/home/shop-web-0.0.1-SNAPSHOT.jar"]
--------------------------------------------------------------------------------
/shop-web/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Dockerfile Maven: https://github.com/spotify/dockerfile-maven
4 | # Use shell script to build Docker image because additional process is required in case of SkyWalking enabled
5 |
6 | # The value will be set by package.sh
7 | APM=zipkin
8 |
9 | DIR=`dirname "$0"`
10 | cd $DIR
11 |
12 | if [ "$APM" = "skywalking" ]; then
13 | cp Dockerfile.skywalking Dockerfile
14 | else
15 | cp Dockerfile.default Dockerfile
16 | fi
17 |
18 | docker build -t mydemo/shopweb .
19 | rm -rf Dockerfile
--------------------------------------------------------------------------------
/shop-web/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SW_AGENT_COLLECTOR_BACKEND_SERVICES=$SKYWALKING_HOST:$SKYWALKING_PORT
4 |
5 | set -ex
6 | eval java $@
--------------------------------------------------------------------------------
/shop-web/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | my.demo
9 | mydemo-parent
10 | 0.0.1-SNAPSHOT
11 |
12 |
13 | shop-web
14 |
15 |
16 | shop-web
17 |
18 |
19 |
20 |
21 |
22 | zipkin
23 |
24 | zipkin
25 |
26 |
27 |
28 | org.springframework.cloud
29 | spring-cloud-starter-zipkin
30 |
31 |
32 |
33 |
34 | seata
35 |
36 |
37 | io.seata
38 | seata-spring-boot-starter
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | src/main/resources
48 | true
49 |
50 | application.yml
51 | application-zipkin.yml
52 | logback.xml
53 | templates/**
54 | static/**
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | my.demo
63 | service-client
64 | 0.0.1-SNAPSHOT
65 |
66 |
67 | org.springframework.boot
68 | spring-boot-starter-web
69 |
70 |
71 | org.hibernate.validator
72 | hibernate-validator
73 |
74 |
75 |
76 |
77 | org.springframework.boot
78 | spring-boot-starter-thymeleaf
79 |
80 |
81 | io.seata
82 | seata-spring-boot-starter
83 | provided
84 | true
85 |
86 |
87 |
88 |
89 |
90 | org.springframework.cloud
91 | spring-cloud-sleuth
92 | 2.2.0.RELEASE
93 | pom
94 | import
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/shop-web/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | docker run -d --net=mydemo --name shopweb -p18090:8090 -e SERVICE_HOST=shopweb -e NACOS_HOST=nacos -e ZIPKIN_HOST=zipkin -e SKYWALKING_HOST=skywalking-oap mydemo/shopweb
--------------------------------------------------------------------------------
/shop-web/src/main/java/my/demo/web/Application.java:
--------------------------------------------------------------------------------
1 | package my.demo.web;
2 |
3 | import org.springframework.boot.WebApplicationType;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.boot.builder.SpringApplicationBuilder;
6 |
7 | @SpringBootApplication(scanBasePackages = {"my.demo.web", "my.demo.utils"})
8 | public class Application {
9 | public static void main(String[] args) {
10 | new SpringApplicationBuilder(Application.class).web(WebApplicationType.SERVLET).run(args);
11 | }
12 | }
--------------------------------------------------------------------------------
/shop-web/src/main/java/my/demo/web/HelloController.java:
--------------------------------------------------------------------------------
1 | package my.demo.web;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.web.bind.annotation.GetMapping;
8 | import org.springframework.web.bind.annotation.PathVariable;
9 | import org.springframework.web.bind.annotation.ResponseBody;
10 |
11 | import com.alibaba.dubbo.config.annotation.Reference;
12 |
13 | import my.demo.service.HelloService;
14 | import my.demo.utils.MyDemoUtils;
15 |
16 | @Controller
17 | public class HelloController {
18 | Logger log = LoggerFactory.getLogger(getClass());
19 |
20 | @Reference(check=false)
21 | HelloService helloService;
22 |
23 | @Value("${mydemo.version}")
24 | String version;
25 | @Value("${mydemo.hostname}")
26 | String hostName;
27 |
28 | @GetMapping(value="/hello/{name}")
29 | public @ResponseBody String hello(@PathVariable(name="name") String name) {
30 | return helloService.hello(name) + ", WEB: " + version + " - " + MyDemoUtils.getIpByHostName(hostName);
31 | }
32 | }
--------------------------------------------------------------------------------
/shop-web/src/main/java/my/demo/web/TestResult.java:
--------------------------------------------------------------------------------
1 | package my.demo.web;
2 |
3 | import java.util.Date;
4 |
5 | import com.fasterxml.jackson.annotation.JsonAutoDetect;
6 | import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
7 | import com.fasterxml.jackson.annotation.JsonFormat;
8 |
9 | @JsonAutoDetect(getterVisibility=Visibility.NONE, setterVisibility=Visibility.NONE, fieldVisibility=Visibility.ANY)
10 | public class TestResult {
11 | private int count;
12 | private long elapsed;
13 | private long elapsedAvg;
14 | @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSS", timezone="Asia/Shanghai")
15 | private Date startAt = new Date();
16 | @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSS", timezone="Asia/Shanghai")
17 | private Date stopAt;
18 | private int success;
19 | private int failed;
20 |
21 | public TestResult stop() {
22 | this.stopAt = new Date();
23 | this.elapsed = this.stopAt.getTime() - this.startAt.getTime();
24 | this.elapsedAvg = this.elapsed / this.count;
25 | return this;
26 | }
27 | public TestResult success() {
28 | this.count++;
29 | this.success++;
30 | return this;
31 | }
32 | public TestResult fail() {
33 | this.failed++;
34 | this.count++;
35 | return this;
36 | }
37 |
38 | public int getCount() {
39 | return count;
40 | }
41 | public void setCount(int count) {
42 | this.count = count;
43 | }
44 | public long getElapsed() {
45 | return elapsed;
46 | }
47 | public void setElapsed(long elapsed) {
48 | this.elapsed = elapsed;
49 | }
50 | public long getElapsedAvg() {
51 | return elapsedAvg;
52 | }
53 | public void setElapsedAvg(long elapsedAvg) {
54 | this.elapsedAvg = elapsedAvg;
55 | }
56 | public Date getStartAt() {
57 | return startAt;
58 | }
59 | public void setStartAt(Date startAt) {
60 | this.startAt = startAt;
61 | }
62 | public Date getStopAt() {
63 | return stopAt;
64 | }
65 | public void setStopAt(Date stopAt) {
66 | this.stopAt = stopAt;
67 | }
68 | public int getSuccess() {
69 | return success;
70 | }
71 | public void setSuccess(int success) {
72 | this.success = success;
73 | }
74 | public int getFailed() {
75 | return failed;
76 | }
77 | public void setFailed(int failed) {
78 | this.failed = failed;
79 | }
80 | }
--------------------------------------------------------------------------------
/shop-web/src/main/resources/application-zipkin.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | zipkin:
3 | base-url: ${zipkin.base-url}
4 | sleuth:
5 | sampler:
6 | percentage: 1.0 # 1.0 stands for 100%
7 |
8 | zipkin:
9 | server: ${zipkin.base-url}/api/v2/spans
10 | connectTimeout: 5000
11 | readTimeout: 5000
--------------------------------------------------------------------------------
/shop-web/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server.port: ${SERVICE_PORT:8090}
2 |
3 | spring:
4 | application:
5 | name: ${application.name}
6 | main:
7 | allow-bean-definition-overriding: true
8 | output:
9 | ansi:
10 | enabled: always
11 | profiles:
12 | include: ${zipkin-profile}
13 | mvc:
14 | static-path-pattern: /static/**
15 |
16 | dubbo:
17 | scan:
18 | basePackages: my.demo.web
19 | application: # see com.alibaba.dubbo.config.ApplicationConfig
20 | id: ${application.name}
21 | name: ${application.name}
22 | qosEnable: false
23 | registry: # see com.alibaba.dubbo.config.RegistryConfig
24 | address: nacos://${nacos.address}
25 | check: false
26 | protocol: # see com.alibaba.dubbo.config.ProtocolConfig
27 | id: dubbo
28 | name: dubbo
29 | host: ${SERVICE_HOST:localhost} # Use POD IP to register Dubbo service
30 | consumer:
31 | filter: ${dubbo.filter}
32 | # Fault tolerance. Options: failover/failfast/failsafe/failback/forking
33 | cluster: failfast
34 | # Load balancing strategy. Options: random, roundrobin(polling), leastactive(invoking least active service)
35 | loadbalance: roundrobin
36 |
37 | seata:
38 | enabled: ${seata-enabled}
39 | application-id: ${application.name}
40 | tx-service-group: my_demo_gtx
41 | config:
42 | type: nacos
43 | nacos:
44 | namespace:
45 | serverAddr: ${nacos.address}
46 | registry:
47 | type: nacos
48 | nacos:
49 | cluster: default
50 | server-addr: ${nacos.address}
51 | namespace:
52 |
53 | nacos.config.server-addr: ${nacos.address}
54 |
55 | mydemo:
56 | version: ${SHOP_VERSION:latest}
57 | hostname: ${HOSTNAME:localhost}
--------------------------------------------------------------------------------
/shop-web/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | UTF-8
15 | ${CONSOLE_LOG_PATTERN:-%clr([%d{${LOG_DATEFORMAT_PATTERN:-yyMMdd HH:mm:ss.SSS}}]){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%-35.35logger{35}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
16 |
17 |
18 |
19 |
20 | UTF-8
21 |
22 | ${CONSOLE_LOG_PATTERN:-%clr([%d{${LOG_DATEFORMAT_PATTERN:-yyMMdd HH:mm:ss.SSS}}]){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} ${log.traceInfo}%clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/shop-web/src/main/resources/static/main.css:
--------------------------------------------------------------------------------
1 | * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
2 |
3 | *, html, body, p, td, th, div, span, input, select, textarea, label, li
4 | { font-size: 16px; font-family:tahoma,arial,'Hiragino Sans GB','\5b8b\4f53',sans-serif; margin:0; padding:0; line-height:18px; }
5 | body { padding:10px; }
6 |
7 | table, tr, td, th { border-collapse:collapse; vertical-align:middle; }
8 | td, th { border-top: 1px solid #999; border-left: 1px solid #999; padding: 1px 2px; }
9 | th { font-weight:600 ; }
10 | table { border-bottom: 1px solid #999; border-right: 1px solid #999; }
11 |
12 | input.text {
13 | outline-style: none ;
14 | border: 1px solid #ccc;
15 | border-radius: 5px;
16 | padding: 10px 4px;
17 | font-size: 16px;
18 | }
19 |
20 | .center {
21 | position:fixed; left:50%;
22 | -webkit-transform: translateX(-50%);
23 | -moz-transform: translateX(-50%);
24 | -ms-transform: translateX(-50%);
25 | transform: translateX(-50%);
26 | }
--------------------------------------------------------------------------------
/stock-service/Dockerfile.default:
--------------------------------------------------------------------------------
1 | FROM mydemo/openjdk:8-jre-alpine
2 |
3 | WORKDIR /home
4 | ENV NACOS_HOST=nacos ZIPKIN_HOST=zipkin SERVICE_PORT=20880
5 | ADD ./target/stock-service-0.0.1-SNAPSHOT.jar /home/
6 | EXPOSE 20880
7 | ENTRYPOINT ["java", "-jar", "/home/stock-service-0.0.1-SNAPSHOT.jar"]
--------------------------------------------------------------------------------
/stock-service/Dockerfile.skywalking:
--------------------------------------------------------------------------------
1 | FROM mydemo/skywalking-base:6.6.0 AS build
2 |
3 | WORKDIR /home/skywalking
4 | RUN rm -rf oap-libs webapp
5 |
6 | FROM mydemo/openjdk:8-jre-alpine
7 |
8 | COPY --from=build /home/skywalking /home/skywalking
9 | ENV NACOS_HOST=nacos SKYWALKING_HOST=skywalking-oap SKYWALKING_PORT=11800 SERVICE_PORT=20880
10 | ADD ./target/stock-service-0.0.1-SNAPSHOT.jar /home/
11 | ADD ./docker-entrypoint.sh /home/
12 | EXPOSE 20880
13 | ENTRYPOINT ["/home/docker-entrypoint.sh", "-javaagent:/home/skywalking/agent/skywalking-agent.jar", "-Dskywalking.agent.service_name=stock-svc", "-Dskywalking.collector.backend_service=$SW_AGENT_COLLECTOR_BACKEND_SERVICES", "-jar", "/home/stock-service-0.0.1-SNAPSHOT.jar"]
--------------------------------------------------------------------------------
/stock-service/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Dockerfile Maven: https://github.com/spotify/dockerfile-maven
4 | # Use shell script to build Docker image because additional process is required in case of SkyWalking enabled
5 |
6 | # The value will be set by package.sh
7 | APM=zipkin
8 |
9 | DIR=`dirname "$0"`
10 | cd $DIR
11 |
12 | if [ "$APM" = "skywalking" ]; then
13 | cp Dockerfile.skywalking Dockerfile
14 | else
15 | cp Dockerfile.default Dockerfile
16 | fi
17 |
18 | docker build -t mydemo/stock .
19 | rm -rf Dockerfile
--------------------------------------------------------------------------------
/stock-service/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SW_AGENT_COLLECTOR_BACKEND_SERVICES=$SKYWALKING_HOST:$SKYWALKING_PORT
4 |
5 | set -ex
6 | eval java $@
--------------------------------------------------------------------------------
/stock-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | my.demo
9 | mydemo-parent
10 | 0.0.1-SNAPSHOT
11 |
12 |
13 | stock-service
14 |
15 |
16 | stock
17 |
18 |
19 |
20 |
21 |
22 | src/main/resources
23 | true
24 |
25 | application.yml
26 | logback.xml
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | my.demo
35 | service-client
36 | 0.0.1-SNAPSHOT
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-starter
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/stock-service/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | docker run -d --net=mydemo --name stock -e SERVICE_HOST=stock -e NACOS_HOST=nacos -e ZIPKIN_HOST=zipkin -e SKYWALKING_HOST=skywalking-oap mydemo/stock
--------------------------------------------------------------------------------
/stock-service/src/main/java/my/demo/service/stock/Application.java:
--------------------------------------------------------------------------------
1 | package my.demo.service.stock;
2 |
3 | import org.springframework.boot.WebApplicationType;
4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
5 | import org.springframework.boot.builder.SpringApplicationBuilder;
6 | import org.springframework.context.annotation.ComponentScan;
7 | import org.springframework.context.annotation.Configuration;
8 |
9 | import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;
10 |
11 | @Configuration
12 | @EnableAutoConfiguration
13 | @ComponentScan(basePackages={"my.demo.service.stock", "my.demo.utils"})
14 | @DubboComponentScan(basePackages = { "my.demo.service.stock" })
15 | public class Application {
16 | public static void main(String[] args) {
17 | new SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE).run(args);
18 | }
19 | }
--------------------------------------------------------------------------------
/stock-service/src/main/java/my/demo/service/stock/StockServiceImpl.java:
--------------------------------------------------------------------------------
1 | package my.demo.service.stock;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import com.alibaba.dubbo.config.annotation.Service;
10 |
11 | import my.demo.entity.Stock;
12 | import my.demo.service.ServiceResult;
13 | import my.demo.service.StockService;
14 | import my.demo.utils.MyDemoUtils;
15 |
16 | @Service
17 | public class StockServiceImpl implements StockService {
18 | Logger log = LoggerFactory.getLogger(this.getClass());
19 |
20 | private Map stocks = new HashMap<>();
21 |
22 | @Override
23 | public ServiceResult getStock(int itemId) {
24 | MyDemoUtils.tag("itemId", itemId);
25 | if(!stocks.containsKey(itemId)) {
26 | synchronized (stocks) {
27 | if(!stocks.containsKey(itemId)) {
28 | Stock stock = new Stock();
29 | stock.setItemId(itemId);
30 | stock.setTotalQty(500);
31 | stocks.put(itemId, stock);
32 | }
33 | }
34 | }
35 | Stock stock = stocks.get(itemId);
36 | if(stock==null) {
37 | log.info("[get] Stock not found, item-id: {}", itemId);
38 | return new ServiceResult<>(null);
39 | }
40 | if(log.isDebugEnabled()) {
41 | log.debug("[get] item-id: {}, available: {}, lock: {}", itemId, stock.getAvailableQty(), stock.getLockQty());
42 | }
43 | return new ServiceResult<>(stock);
44 | }
45 |
46 | @Override
47 | public ServiceResult lock(int itemId, int lockQty) {
48 | MyDemoUtils.tag("itemId", itemId);
49 | MyDemoUtils.tag("lockQty", lockQty);
50 | if(!stocks.containsKey(itemId)) {
51 | log.info("[lock] Stock not found, item-id: {}", itemId);
52 | return new ServiceResult().fail("Item " + itemId + " not found");
53 | }
54 | if(lockQty<=0) {
55 | return new ServiceResult().fail("Illegal quantity " + lockQty + " to lock");
56 | }
57 |
58 | Stock stock = stocks.get(itemId);
59 | synchronized (stock) {
60 | if(stock.getAvailableQty() < lockQty) {
61 | log.info("[lock] Failed, item-id: {}, avalaible: {}, request: {}", itemId, stock.getAvailableQty(), lockQty);
62 | return new ServiceResult<>(false);
63 | }
64 | log.info("[lock] Success, item-id: {}, avalaible: {}, request: {}", itemId, stock.getAvailableQty(), lockQty);
65 | stock.setLockQty(stock.getLockQty() + lockQty);
66 | return new ServiceResult<>(true);
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/stock-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | main:
3 | allow-bean-definition-overriding: true
4 | output:
5 | ansi:
6 | enabled: always
7 |
8 | dubbo:
9 | application: # see com.alibaba.dubbo.config.ApplicationConfig
10 | id: ${application.name}-srv
11 | name: ${application.name}-srv
12 | qosEnable: false
13 | protocol: # see com.alibaba.dubbo.config.ProtocolConfig
14 | id: dubbo
15 | name: dubbo
16 | host: ${SERVICE_HOST:localhost} # Use POD IP to register Dubbo service
17 | port: ${SERVICE_PORT:20881}
18 | threads: 3
19 | iothreads: 1
20 | server: netty
21 | client: netty
22 | status: server
23 | serialization: fst
24 | queues: 0
25 | keepAlive: true
26 | registry: # see com.alibaba.dubbo.config.RegistryConfig
27 | address: nacos://${nacos.address}
28 | check: false
29 | provider:
30 | cluster: failfast
31 | retries: 0
32 | loadbalance: roundrobin
33 | timeout: 10000
34 | filter: ${dubbo.filter}
35 |
36 | zipkin:
37 | server: ${zipkin.base-url}/api/v2/spans
38 | connectTimeout: 5000
39 | readTimeout: 5000
--------------------------------------------------------------------------------
/stock-service/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | UTF-8
15 | ${CONSOLE_LOG_PATTERN:-%clr([%d{${LOG_DATEFORMAT_PATTERN:-yyMMdd HH:mm:ss.SSS}}]){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%-35.35logger{35}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
16 |
17 |
18 |
19 |
20 | UTF-8
21 |
22 | ${CONSOLE_LOG_PATTERN:-%clr([%d{${LOG_DATEFORMAT_PATTERN:-yyMMdd HH:mm:ss.SSS}}]){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} ${log.traceInfo}%clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/user-service/Dockerfile.default:
--------------------------------------------------------------------------------
1 | FROM mydemo/openjdk:8-jre-alpine
2 |
3 | WORKDIR /home
4 | ENV MYSQL_HOST=mysql NACOS_HOST=nacos ZIPKIN_HOST=zipkin SERVICE_PORT=20880
5 | ADD ./target/user-service-0.0.1-SNAPSHOT.jar /home/
6 | EXPOSE 20880
7 | ENTRYPOINT ["java", "-jar", "/home/user-service-0.0.1-SNAPSHOT.jar"]
--------------------------------------------------------------------------------
/user-service/Dockerfile.skywalking:
--------------------------------------------------------------------------------
1 | FROM mydemo/skywalking-base:6.6.0 AS build
2 |
3 | WORKDIR /home/skywalking
4 | RUN rm -rf oap-libs webapp
5 |
6 | FROM mydemo/openjdk:8-jre-alpine
7 |
8 | COPY --from=build /home/skywalking /home/skywalking
9 | ENV MYSQL_HOST=mysql NACOS_HOST=nacos SKYWALKING_HOST=skywalking-oap SKYWALKING_PORT=11800 SERVICE_PORT=20880
10 | ADD ./target/user-service-0.0.1-SNAPSHOT.jar /home/
11 | ADD ./docker-entrypoint.sh /home/
12 | EXPOSE 20880
13 | ENTRYPOINT ["/home/docker-entrypoint.sh", "-javaagent:/home/skywalking/agent/skywalking-agent.jar", "-Dskywalking.agent.service_name=user-svc", "-Dskywalking.collector.backend_service=$SW_AGENT_COLLECTOR_BACKEND_SERVICES", "-jar", "/home/user-service-0.0.1-SNAPSHOT.jar"]
--------------------------------------------------------------------------------
/user-service/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Dockerfile Maven: https://github.com/spotify/dockerfile-maven
4 | # Use shell script to build Docker image because additional process is required in case of SkyWalking enabled
5 |
6 | # The value will be set by package.sh
7 | APM=zipkin
8 |
9 | DIR=`dirname "$0"`
10 | cd $DIR
11 |
12 | if [ "$APM" = "skywalking" ]; then
13 | cp Dockerfile.skywalking Dockerfile
14 | else
15 | cp Dockerfile.default Dockerfile
16 | fi
17 |
18 | docker build -t mydemo/user .
19 | rm -rf Dockerfile
--------------------------------------------------------------------------------
/user-service/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SW_AGENT_COLLECTOR_BACKEND_SERVICES=$SKYWALKING_HOST:$SKYWALKING_PORT
4 |
5 | set -ex
6 | eval java $@
--------------------------------------------------------------------------------
/user-service/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # The value will be set by package.sh
4 | MYSQL_HOST=mysql
5 | docker run -d --net=mydemo --name user -e SERVICE_HOST=user -e MYSQL_HOST=$MYSQL_HOST -e NACOS_HOST=nacos -e ZIPKIN_HOST=zipkin -e SKYWALKING_HOST=skywalking-oap mydemo/user
--------------------------------------------------------------------------------
/user-service/src/main/java/my/demo/dao/user/UserDao.java:
--------------------------------------------------------------------------------
1 | package my.demo.dao.user;
2 |
3 | import org.apache.ibatis.annotations.Insert;
4 | import org.apache.ibatis.annotations.Mapper;
5 | import org.apache.ibatis.annotations.Options;
6 | import org.apache.ibatis.annotations.Param;
7 | import org.apache.ibatis.annotations.ResultMap;
8 | import org.apache.ibatis.annotations.Select;
9 |
10 | import my.demo.entity.User;
11 | import my.demo.entity.UserAccount;
12 |
13 | @Mapper
14 | public interface UserDao {
15 | @Select("select * from usr_user_account where account=#{account} and account_hash=#{accountHash}")
16 | @ResultMap("userAccount")
17 | UserAccount getUserAccount(@Param("account") String account, @Param("accountHash") int accountHash);
18 |
19 | @Insert("insert into usr_user_account(account, password, user_id, account_hash) values (#{account}, #{password}, #{userId}, #{accountHash})")
20 | int createUserAccount(UserAccount userAccount);
21 |
22 | @Select("select * from usr_user where user_id=#{userId}")
23 | @ResultMap("user")
24 | User getUser(long userId);
25 |
26 | /**
27 | * ATTENTION:
28 | *
29 | * Without Mycat and Sharding-Proxy, user_id is generated by MySQL auto increment, both last_insert_id()
and GENERATED_KEY
can be used to get last inserted value;
30 | * With Mycat, user_id is generated by Mycat global sequence, both last_insert_id()
and GENERATED_KEY
can be used to get last inserted value, see docs/Sharding-Mycat-Overview-Quickstart.md;
31 | * With Sharding-Proxy, user_id is generated by Sharding-Proxy, GENERATED_KEY
is the only way to get last inserted value, see docs/Sharding-Sharding-Proxy-Overview-Quickstart.md;
32 | *
33 | * @param user
34 | * @return
35 | */
36 | @Insert("insert into usr_user (nickname, mobile, email, created_at) values (#{nickname}, #{mobile}, #{email}, #{createdAt})")
37 | @Options(useGeneratedKeys=true, keyProperty="userId", keyColumn="user_id")
38 | int createUser(User user);
39 | }
--------------------------------------------------------------------------------
/user-service/src/main/java/my/demo/service/user/Application.java:
--------------------------------------------------------------------------------
1 | package my.demo.service.user;
2 |
3 | import org.mybatis.spring.annotation.MapperScan;
4 | import org.springframework.boot.WebApplicationType;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.boot.builder.SpringApplicationBuilder;
7 |
8 | import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
9 |
10 | @SpringBootApplication(scanBasePackages = {"my.demo.service.user", "my.demo.utils"})
11 | @MapperScan(basePackages = { "my.demo.dao.user" })
12 | @EnableDubbo(scanBasePackages = { "my.demo.service.user" })
13 | public class Application {
14 | public static void main(String[] args) {
15 | new SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE).run(args);
16 | }
17 | }
--------------------------------------------------------------------------------
/user-service/src/main/java/my/demo/service/user/HelloServiceImpl.java:
--------------------------------------------------------------------------------
1 | package my.demo.service.user;
2 |
3 | import java.text.SimpleDateFormat;
4 | import java.util.Date;
5 |
6 | import org.springframework.beans.factory.annotation.Value;
7 |
8 | import com.alibaba.dubbo.config.annotation.Service;
9 |
10 | import my.demo.service.HelloService;
11 | import my.demo.utils.MyDemoUtils;
12 |
13 | @Service
14 | public class HelloServiceImpl implements HelloService {
15 | @Value("${mydemo.hostname}")
16 | String hostName;
17 | SimpleDateFormat sdf = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss SSS] ");
18 |
19 | @Override
20 | public String hello(String name) {
21 | return sdf.format(new Date()) + "Hello " + name + " from SVC: " + MyDemoUtils.getIpByHostName(hostName);
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/user-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | # Bug fix for MySQL JDBC driver:
2 | # CST: Central Standard Time (USA) UT-6:00
3 | # CST: Central Standard Time (Australia) UT+9:30
4 | # CST: China Standard Time UT+8:00
5 | # CST: Cuba Standard Time UT-4:00
6 | # MySQL Server get timezone from OS, show variables like '%time_zone%':
7 | # | Variable_name | Value |
8 | # | system_time_zone | CST |
9 | # | time_zone | SYSTEM |
10 | # java.util.Date is converted to java.sql.Timestamp and passed to MySQL JDBC Driver by MyBatis DateTypeHandler,
11 | # MySQL JDBC Driver uses timezone CST to process Timestamp parameters,
12 | # the actual timezone it takes is Central Standard Time (USA) UT-6:00, not China Standard Time UT+8:00.
13 | # Specify serverTimezone=Asia/Shanghai parameter in JDBC url to avoid this problem.
14 | spring:
15 | main:
16 | allow-bean-definition-overriding: true
17 | output:
18 | ansi:
19 | enabled: always
20 | datasource:
21 | driver-class-name: ${mysql.driver-class}
22 | url: jdbc:mysql://${mysql.host}:${mysql.port}/${db.user}?connectTimeout=3000&socketTimeout=10000&characterEncoding=utf8&useTimezone=true&serverTimezone=Asia/Shanghai&useSSL=false${jdbc.interceptors}
23 | username: ${mysql.user}
24 | password: ${mysql.password}
25 |
26 | dubbo:
27 | application: # see com.alibaba.dubbo.config.ApplicationConfig
28 | id: ${application.name}-srv
29 | name: ${application.name}-srv
30 | qosEnable: false
31 | protocol: # see com.alibaba.dubbo.config.ProtocolConfig
32 | id: dubbo
33 | name: dubbo
34 | host: ${SERVICE_HOST:localhost} # Use POD IP to register Dubbo service
35 | port: ${SERVICE_PORT:20882}
36 | threads: 3
37 | iothreads: 1
38 | server: netty
39 | client: netty
40 | status: server
41 | serialization: fst
42 | queues: 0
43 | keepAlive: true
44 | registry: # see com.alibaba.dubbo.config.RegistryConfig
45 | address: nacos://${nacos.address}
46 | check: false
47 | provider:
48 | cluster: failfast
49 | retries: 0
50 | loadbalance: roundrobin
51 | timeout: 10000
52 | filter: ${dubbo.filter}
53 |
54 | druid:
55 | defaultAutoCommit: true
56 | defaultTransactionIsolation: 2
57 | initialSize: 1
58 | maxActive: 3
59 | maxWait: 5000
60 | minIdle: 1
61 | validationQuery: /* ping */ select 1
62 | testOnBorrow: false
63 | testOnReturn: false
64 | testWhileIdle: true
65 | timeBetweenEvictionRunsMillis: 60000
66 | minEvictableIdleTimeMillis: 1800000
67 | removeAbandoned: true
68 | removeAbandonedTimeout: 1800
69 | logAbandoned: true
70 |
71 | mybatis: # see MybatisProperties.class in mybatis-spring-boot-autoconfigure
72 | mapperLocations: classpath:mappers/*.xml
73 |
74 | seata:
75 | enabled: true
76 | application-id: ${application.name}
77 | tx-service-group: my_demo_gtx
78 | config:
79 | type: nacos
80 | nacos:
81 | namespace:
82 | serverAddr: ${nacos.address}
83 | registry:
84 | type: nacos
85 | nacos:
86 | cluster: default
87 | server-addr: ${nacos.address}
88 | namespace:
89 |
90 | zipkin:
91 | server: ${zipkin.base-url}/api/v2/spans
92 | connectTimeout: 5000
93 | readTimeout: 5000
94 |
95 | mydemo:
96 | hostname: ${HOSTNAME:localhost}
--------------------------------------------------------------------------------
/user-service/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | UTF-8
15 | ${CONSOLE_LOG_PATTERN:-%clr([%d{${LOG_DATEFORMAT_PATTERN:-yyMMdd HH:mm:ss.SSS}}]){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%-35.35logger{35}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
16 |
17 |
18 |
19 |
20 | UTF-8
21 |
22 | ${CONSOLE_LOG_PATTERN:-%clr([%d{${LOG_DATEFORMAT_PATTERN:-yyMMdd HH:mm:ss.SSS}}]){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} ${log.traceInfo}%clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/user-service/src/main/resources/mappers/UserMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/user-service/src/test/java/my/demo/service/user/test/UserServiceImplTest.java:
--------------------------------------------------------------------------------
1 | package my.demo.service.user.test;
2 |
3 | import org.testng.Assert;
4 | import org.testng.annotations.Test;
5 |
6 | import my.demo.entity.User;
7 | import my.demo.service.ServiceResult;
8 | import my.demo.service.user.UserServiceImpl;
9 |
10 | public class UserServiceImplTest {
11 | @Test
12 | public void testCheckAccountAndPassword() {
13 | UserServiceImpl service = new UserServiceImpl();
14 | ServiceResult result = new ServiceResult<>();
15 | service.checkAccountAndPassword(result, "13966668888", "qwe123");
16 | Assert.assertTrue(result.isSuccess());
17 |
18 | service.checkAccountAndPassword(result, "", "qwe123");
19 | Assert.assertFalse(result.isSuccess());
20 | Assert.assertEquals(result.getMessage(), UserServiceImpl.EMPTY_ACCOUNT);
21 | service.checkAccountAndPassword(result, "139666688a8", "qwe123");
22 | Assert.assertFalse(result.isSuccess());
23 | Assert.assertEquals(result.getMessage(), UserServiceImpl.INVALID_ACCOUNT);
24 | service.checkAccountAndPassword(result, "1396668", "qwe123");
25 | Assert.assertFalse(result.isSuccess());
26 | Assert.assertEquals(result.getMessage(), UserServiceImpl.INVALID_ACCOUNT);
27 |
28 | service.checkAccountAndPassword(result, "13966668888", "");
29 | Assert.assertFalse(result.isSuccess());
30 | Assert.assertEquals(result.getMessage(), UserServiceImpl.EMPTY_PASSWORD);
31 | service.checkAccountAndPassword(result, "13966668888", "qwe23");
32 | Assert.assertFalse(result.isSuccess());
33 | Assert.assertEquals(result.getMessage(), UserServiceImpl.INVALID_PASSWORD);
34 | service.checkAccountAndPassword(result, "13966668888", "QQQQQQ");
35 | Assert.assertFalse(result.isSuccess());
36 | Assert.assertEquals(result.getMessage(), UserServiceImpl.INVALID_PASSWORD);
37 | }
38 | }
--------------------------------------------------------------------------------