Sock Shop

Sock Shop simulates the user-facing part of an e-commerce website that sells socks. It is intended to aid the demonstration and testing of microservice and cloud native technologies.

It is built using Spring Boot, Go kit and Node.js and is packaged in Docker containers.

Sock Shop microservices are designed to have minimal expectations, using DNS to find other services. This means that it is possible to insert load-balancers and service routers, as required or desired.

Deploying Sock Shop on any Kubernetes cluster

Pre-requisites

  • Kubernetes linux cluster
  • Configured kubectl to connect to the cluster

Deploy Sock Shop

Clone the microservices-demo repository

git clone https://github.com/microservices-demo/microservices-demo.git

Go to the deploy/kubernetes folder

cd microservices-demo/deploy/kubernetes/
kubectl create namespace sock-shop

kubectl apply -f complete-demo.yaml

Go to http://cluster-ip:30001/

User Accounts

To log into Sock Shop and complete a transaction, you'll need credentials. The 'user' microservice ships with the following accounts.

Username Password
user password
user1 password
Eve_Berger eve

Monitoring

kubectl create namespace monitoring
kubectl create clusterrolebinding your-user-cluster-admin-binding --clusterrole=cluster-admin --user=adithya.sankar321@gmail.com
clusterrolebinding.rbac.authorization.k8s.io/your-user-cluster-admin-binding created
kubectl create -f manifests-monitoring

Go to http://cluster-ip:31090/graph

Design

Direction

The goal of this project is to become a "reference microservices demo". To this end, it aims to:

  • Demonstrate microservice best practices (and mistakes!)
  • Be cross-platform: deploy to all orchestrators
  • Show the benefits of continuous integration/deployment
  • Demonstrate how dev-ops and microservices compliment each other
  • Provide a "real-life" testable application for various orchestration platforms

Architecture

Architecture

The architecture of the demo microserivces application was intentionally designed to provide as many microservices as possible. If you are considering your own design, we would recommend the iterative approach, whereby you only define new microservices when you see issues (performance/testing/coupling) developing in your application.

Furthermore, it is intentionally polyglot to exercise a number of different technologies. Again, we'd recommend that you only consider new technologies based upon a need.

All services communicate using REST over HTTP. This was chosen due to the simplicity of development and testing. Their API specifications are under development.

Services

Front-end app

Front-end application written in Node.js that puts together all of the microservices under microservices-demo.

Orders

Spring-Boot Java

A microservices-demo service that provides ordering capabilities.

Orders.NET

The orders service (written in .NET) for the Microservices Demo.

Payment

A microservices-demo service written in Go that provides payment services.

User

This service, written in Go, covers user account storage, to include cards and addresses

Catalogue

A microservices-demo service written in Go that provides catalogue/product information. Checkout the API Spec here

Cart

A Spring Boot service that provides shopping carts for users.

Shipping

A microservices-demo service that provides shipping capabilities.

Queue Master

A microservices-demo service that provides reading from the shipping queue. It will spawn new docker containers that simulate the shipping process.

Log Server

This is a Fluentd based container that is used to ship logs for all the services in the microservices-demo project.

Tests

Load / Integration Tests

These tests simulate actual end user usage of the application. They are used to validate the overall functionality and can also be used to put simulated load on the system. The tests are written using locust.io

git clone https://github.com/microservices-demo/load-test.git
cd load-test

vim Dockerfile

Change locustio to locustio==0.8.1

# Install locust
RUN pip install pyzmq locustio==0.8.1 faker
sudo docker build -t load-test .
sudo docker run load-test -h [host] -c [number of clients] -r [number of requests]
sudo docker run load-test -h 35.206.106.166:30001 -c 100 -r 1000
Locust file: /config/locustfile.py
Will run /config/locustfile.py against 35.206.106.166:30001. Spawning 100 clients and 1000 total requests.
[2019-05-02 09:26:09,662] cb17a78aa225/INFO/locust.main: Starting Locust 0.8.1
[2019-05-02 09:26:09,662] cb17a78aa225/INFO/locust.runners: Hatching and swarming 100 clients at the rate 5 clients/s...
[2019-05-02 09:26:29,770] cb17a78aa225/INFO/locust.runners: All locusts hatched: Web: 100
[2019-05-02 09:26:29,770] cb17a78aa225/INFO/locust.runners: Resetting stats

[2019-05-02 09:26:29,770] cb17a78aa225/INFO/locust.runners: All locusts dead

[2019-05-02 09:26:29,771] cb17a78aa225/INFO/locust.main: Shutting down (exit code 1), bye.
 Name                                                          # reqs      # fails     Avg     Min     Max  |  Median   req/s
--------------------------------------------------------------------------------------------------------------------------------------------
 GET /                                                              0     0(0.00%)       0       0       0  |       0    0.00
 GET /basket.html                                                   0     0(0.00%)       0       0       0  |       0    0.00
 DELETE /cart                                                       0     0(0.00%)       0       0       0  |       0    0.00
 POST /cart                                                         0     0(0.00%)       0       0       0  |       0    0.00
 GET /catalogue                                                     0     0(0.00%)       0       0       0  |       0    0.00
 GET /category.html                                                 0     0(0.00%)       0       0       0  |       0    0.00
 GET /detail.html?id=03fef6ac-1896-4ce8-bd69-b798f85c6e0b           0     0(0.00%)       0       0       0  |       0    0.00
 GET /detail.html?id=3395a43e-2d88-40de-b95f-e00e1502085b           0     0(0.00%)       0       0       0  |       0    0.00
 GET /detail.html?id=510a0d7e-8e83-4193-b483-e27e09ddc34d           0     0(0.00%)       0       0       0  |       0    0.00
 GET /detail.html?id=808a2de1-1aaa-4c25-a9b9-6612e8f29a38           0     0(0.00%)       0       0       0  |       0    0.00
 GET /detail.html?id=819e1fbf-8b7e-4f6d-811f-693534916a8b           0     0(0.00%)       0       0       0  |       0    0.00
 GET /detail.html?id=837ab141-399e-4c1f-9abc-bace40296bac           0     0(0.00%)       0       0       0  |       0    0.00
 GET /detail.html?id=a0a4f044-b040-410d-8ead-4de0446aec7e           0     0(0.00%)       0       0       0  |       0    0.00
 GET /detail.html?id=d3588630-ad8e-49df-bbd7-3167f7efb246           0     0(0.00%)       0       0       0  |       0    0.00
 GET /detail.html?id=zzz4f044-b040-410d-8ead-4de0446aec7e           0     0(0.00%)       0       0       0  |       0    0.00
 GET /login                                                         0     0(0.00%)       0       0       0  |       0    0.00
 POST /orders                                                       0     0(0.00%)       0       0       0  |       0    0.00
--------------------------------------------------------------------------------------------------------------------------------------------
 Total                                                              0     0(0.00%)                                       0.00

Percentage of the requests completed within given times
 Name                                                           # reqs    50%    66%    75%    80%    90%    95%    98%    99%   100%
--------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------

Error report
 # occurences       Error
--------------------------------------------------------------------------------------------------------------------------------------------
 11                 POST /orders: "HTTPError(u'406 Client Error: Not Acceptable for url: http://35.206.106.166:30001/orders',)"
--------------------------------------------------------------------------------------------------------------------------------------------

done

Prometheus after load-test

End-to-End tests

This repo contains a a set of end-to-end tests, that we use to verify that changes to the shop don't cause regressions.

Futhermore, it can be used to verify that swapping out a service (lets say the payment service) by one implemented in a different language, that things still work as intended.

How to run these tests

git clone https://github.com/microservices-demo/e2e-tests.git
cd e2e-tests/

By running the following commands, all tests in the tests directory will be run:

sudo docker build -t weaveworksdemos/e2etests .
cd tests
sudo docker run --rm -e URL=<HOSTNAME> weaveworksdemos/e2etests
sudo docker run --rm -e URL=35.206.106.166:30001 weaveworksdemos/e2etests
Testing /e2etests/tests/add_holy_to_cart.rb
You're running an old version of PhantomJS, update to >= 2.1.1 for a better experience.
Fontconfig error: Cannot load default config file
Testing /e2etests/tests/checkout_holy.rb
Testing /e2etests/tests/login.rb
Loading components for index.html
Loading components for category.html
Sending request to add to cart: 03fef6ac-1896-4ce8-bd69-b798f85c6e0b
Item added: 03fef6ac-1896-4ce8-bd69-b798f85c6e0b, success
Loading components for category.html
Loading components for index.html
Loading components for category.html
Loading components for index.html
posted: success
logged_in cookie: nCoywCKnt1LE1GrdQHr_yhWuxPToqT75
Loading components for index.html
Requesting user account information nCoywCKnt1LE1GrdQHr_yhWuxPToqT75
2 test(s) passed, 1 test(s) failed.
/e2etests/tests/checkout_holy.rb:
AssertError
/nix/store/nl57jq7lsnz9bcy2gkzj3i23c8nh99hs-e2etest:19:in `assert!'
/e2etests/tests/checkout_holy.rb:8:in `block in <top (required)>'
/nix/store/nl57jq7lsnz9bcy2gkzj3i23c8nh99hs-e2etest:69:in `instance_eval'
/nix/store/nl57jq7lsnz9bcy2gkzj3i23c8nh99hs-e2etest:69:in `block in <top (required)>'
/nix/store/nl57jq7lsnz9bcy2gkzj3i23c8nh99hs-e2etest:64:in `each'
/nix/store/nl57jq7lsnz9bcy2gkzj3i23c8nh99hs-e2etest:64:in `<top (required)>'
/nix/store/qjd7svkxlvnzaz58rbfc5crh75gvvncs-bundler-1.12.5/lib/ruby/gems/2.3.1/gems/bundler-1.12.5/lib/bundler/cli/exec.rb:63:in `load'
/nix/store/qjd7svkxlvnzaz58rbfc5crh75gvvncs-bundler-1.12.5/lib/ruby/gems/2.3.1/gems/bundler-1.12.5/lib/bundler/cli/exec.rb:63:in `kernel_load'
/nix/store/qjd7svkxlvnzaz58rbfc5crh75gvvncs-bundler-1.12.5/lib/ruby/gems/2.3.1/gems/bundler-1.12.5/lib/bundler/cli/exec.rb:24:in `run'
/nix/store/qjd7svkxlvnzaz58rbfc5crh75gvvncs-bundler-1.12.5/lib/ruby/gems/2.3.1/gems/bundler-1.12.5/lib/bundler/cli.rb:304:in `exec'
/nix/store/qjd7svkxlvnzaz58rbfc5crh75gvvncs-bundler-1.12.5/lib/ruby/gems/2.3.1/gems/bundler-1.12.5/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/nix/store/qjd7svkxlvnzaz58rbfc5crh75gvvncs-bundler-1.12.5/lib/ruby/gems/2.3.1/gems/bundler-1.12.5/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
/nix/store/qjd7svkxlvnzaz58rbfc5crh75gvvncs-bundler-1.12.5/lib/ruby/gems/2.3.1/gems/bundler-1.12.5/lib/bundler/vendor/thor/lib/thor.rb:359:in `dispatch'
/nix/store/qjd7svkxlvnzaz58rbfc5crh75gvvncs-bundler-1.12.5/lib/ruby/gems/2.3.1/gems/bundler-1.12.5/lib/bundler/vendor/thor/lib/thor/base.rb:440:in `start'
/nix/store/qjd7svkxlvnzaz58rbfc5crh75gvvncs-bundler-1.12.5/lib/ruby/gems/2.3.1/gems/bundler-1.12.5/lib/bundler/cli.rb:11:in `start'
/nix/store/qjd7svkxlvnzaz58rbfc5crh75gvvncs-bundler-1.12.5/lib/ruby/gems/2.3.1/gems/bundler-1.12.5/exe/bundle:27:in `block in <top (required)>'
/nix/store/qjd7svkxlvnzaz58rbfc5crh75gvvncs-bundler-1.12.5/lib/ruby/gems/2.3.1/gems/bundler-1.12.5/lib/bundler/friendly_errors.rb:98:in `with_friendly_errors'
/nix/store/qjd7svkxlvnzaz58rbfc5crh75gvvncs-bundler-1.12.5/lib/ruby/gems/2.3.1/gems/bundler-1.12.5/exe/bundle:19:in `<top (required)>'
/nix/store/xkz4dyy4fm5ks35psw7bqrkq55si2n8j-e2e-ruby-env/bin/bundle:18:in `load'
/nix/store/xkz4dyy4fm5ks35psw7bqrkq55si2n8j-e2e-ruby-env/bin/bundle:18:in `<main>'

results matching ""

    No results matching ""