├── .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 | ![](../docs/images/docker-download-curl.png) 8 | - `wget`:
9 | ![](../docs/images/docker-download-wget.png) 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 | 6 | 11 | 12 |
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 | 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 | ![](../docs/images/postman.jpg) 4 | 5 | `newman` is a command line tool for running `Postman` tests in shell, it can work with Jenkins:
6 | ![](../docs/images/newman-output.jpg) 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 | *
  1. 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;
  2. 30 | *
  3. 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;
  4. 31 | *
  5. 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;
  6. 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 | } --------------------------------------------------------------------------------