Code Monkey home page Code Monkey logo

goblog's Introduction

goblog

Code samples for the Go microservice blog series

Changelog

  • 2019-07-27: Total rewrite of Go code, including introducing Makefiles for build and a docker-compose file for deployment on Docker Swarm.

Some URLs to remember

Turbine stream URL: http://192.168.99.100:8282/turbine.stream?cluster=swarm Hystrix stream URL: http://accountservice:8181/hystrix.stream?cluster=swarm

Make sure Turbine doesn't crash on startup due to AMQ connection problem.

Setting up Docker Swarm cluster

docker-machine create --driver virtualbox --virtualbox-cpu-count 4 --virtualbox-memory 6000 --virtualbox-disk-size 30000 swarm-manager-0
eval "$(docker-machine env swarm-manager-0)"
docker network create --driver overlay my_network
docker swarm init --advertise-addr 192.168.99.100
Adding a worker node
docker swarm join --token SWMTKN-1-5njothki0tww7gestuh309qgrnr6r357phlsn7ue0r8qmlqnla-181tl1rfou16vv3e7nxrk4ra3 192.168.99.100:2377

Building

You need Go 1.14 or later installed on your system to build from source.

Builds are performed using Makefile(s). In the root /goblog folder:

make build

One can also run all tests, format code using makefile targets.

Deploying

Deploy using:

make deploy

The make target uses docker stack deploy behind the scenes.

Nice to haves

Here's some minor stuff worth remembering.

Running the CockroachDB client

Find a container running the cockroachdb/cockroach container using docker ps and note the container ID. Then we'll use docker exec to launch the SQL CLI:

> docker exec -it 10f4b6c727f8 ./cockroach sql --insecure

Create user and database for Cockroach

(this is possibly broken, from part 16 onwards the initial DB setup is performed using the docker stack)

Originally from: cockroachdb/cockroach#19826 (comment)

DROP USER IF EXISTS cockroach; \
DROP DATABASE IF EXISTS account CASCADE; \
CREATE DATABASE IF NOT EXISTS account; \
CREATE USER cockroach WITH PASSWORD 'password'; \
GRANT ALL ON DATABASE account TO cockroach;

goblog's People

Contributors

eriklupander avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

goblog's Issues

missing library `se.callista.microservises:util:0.0.1-SNAPSHOT`

I built it from the repo of java microservice blog series.

diff --git a/support/edge-server/build.gradle b/support/edge-server/build.gradle
index fdf0e12..af6f1fb 100644
--- a/support/edge-server/build.gradle
+++ b/support/edge-server/build.gradle
@@ -49,7 +49,8 @@ dependencies {
     // compile("org.springframework.cloud:spring-cloud-starter-oauth2")
     // compile("org.springframework.cloud:spring-cloud-starter-security")

-     compile("se.callista.microservises:util:0.0.1-SNAPSHOT")
+    // compile("se.callista.microservises:util:0.0.1-SNAPSHOT")
+    compile files('libs/util-0.0.1-SNAPSHOT.jar')

      testCompile('org.springframework.boot:spring-boot-starter-test')
 }

Hi. Go microservices, part 7 - Service Discovery & Load-balancing.

Hello, when I execute the command
docker service scale accountservice=3,
use the curl $ManagerIP:6767/accounts/10000 command to verify that all the same ip is returned to the service without seeing the ip transform. effect...

use command:

docker service inspect $service
docker inspect $container

Tracing package is obsolete.Updated version is below.

package tracing

import (
	"context"
	"fmt"
	"net/http"

	"github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/ext"
	zipkinot "github.com/openzipkin-contrib/zipkin-go-opentracing"
	"github.com/openzipkin/zipkin-go"
	zipkinhttp "github.com/openzipkin/zipkin-go/reporter/http"
	"github.com/sirupsen/logrus"
)

// Tracer instance
var tracer opentracing.Tracer

// SetTracer can be used by unit tests to provide a NoopTracer instance. Real users should always
// use the InitTracing func.
func SetTracer(initializedTracer opentracing.Tracer) {
	tracer = initializedTracer
}

// InitTracing connects the calling service to Zipkin and initializes the tracer.
func InitTracing(zipkinURL string, serviceName string) {
	logrus.Infof("Connecting to zipkin server at %v", zipkinURL)
	reporter := zipkinhttp.NewReporter(fmt.Sprintf("%s/api/v1/spans", zipkinURL))

	endpoint, err := zipkin.NewEndpoint(serviceName, "127.0.0.1:0")
	if err != nil {
		logrus.Fatalf("unable to create local endpoint: %+v\n", err)
	}

	nativeTracer, err := zipkin.NewTracer(reporter, zipkin.WithLocalEndpoint(endpoint))
	if err != nil {
		logrus.Fatalf("unable to create tracer: %+v\n", err)
	}

	// use zipkin-go-opentracing to wrap our tracer
	tracer = zipkinot.Wrap(nativeTracer)

	logrus.Infof("Successfully started zipkin tracer for service '%v'", serviceName)
}

// StartHTTPTrace loads tracing information from an INCOMING HTTP request.
func StartHTTPTrace(r *http.Request, opName string) opentracing.Span {
	carrier := opentracing.HTTPHeadersCarrier(r.Header)
	clientContext, err := tracer.Extract(opentracing.HTTPHeaders, carrier)
	if err == nil {
		return tracer.StartSpan(
			opName, ext.RPCServerOption(clientContext))
	} else {
		return tracer.StartSpan(opName)
	}
}

// MapToCarrier converts a generic map to opentracing http headers carrier
func MapToCarrier(headers map[string]interface{}) opentracing.HTTPHeadersCarrier {
	carrier := make(opentracing.HTTPHeadersCarrier)
	for k, v := range headers {
		// delivery.Headers
		carrier.Set(k, v.(string))
	}
	return carrier
}

// CarrierToMap converts a TextMapCarrier to the amqp headers format
func CarrierToMap(values map[string]string) map[string]interface{} {
	headers := make(map[string]interface{})
	for k, v := range values {
		headers[k] = v
	}
	return headers
}

// StartTraceFromCarrier extracts tracing info from a generic map and starts a new span.
func StartTraceFromCarrier(carrier map[string]interface{}, spanName string) opentracing.Span {

	clientContext, err := tracer.Extract(opentracing.HTTPHeaders, MapToCarrier(carrier))
	var span opentracing.Span
	if err == nil {
		span = tracer.StartSpan(
			spanName, ext.RPCServerOption(clientContext))
	} else {
		span = tracer.StartSpan(spanName)
	}
	return span
}

// AddTracingToReq adds tracing information to an OUTGOING HTTP request
func AddTracingToReq(req *http.Request, span opentracing.Span) {
	carrier := opentracing.HTTPHeadersCarrier(req.Header)
	err := tracer.Inject(
		span.Context(),
		opentracing.HTTPHeaders,
		carrier)
	if err != nil {
		panic("Unable to inject tracing context: " + err.Error())
	}
}

// AddTracingToReqFromContext adds tracing information to an OUTGOING HTTP request
func AddTracingToReqFromContext(ctx context.Context, req *http.Request) {
	if ctx.Value("opentracing-span") == nil {
		return
	}
	carrier := opentracing.HTTPHeadersCarrier(req.Header)
	err := tracer.Inject(
		ctx.Value("opentracing-span").(opentracing.Span).Context(),
		opentracing.HTTPHeaders,
		carrier)
	if err != nil {
		panic("Unable to inject tracing context: " + err.Error())
	}
}

func AddTracingToTextMapCarrier(span opentracing.Span, val opentracing.TextMapCarrier) error {
	return tracer.Inject(span.Context(), opentracing.TextMap, val)
}

// StartSpanFromContext starts a span.
func StartSpanFromContext(ctx context.Context, opName string) opentracing.Span {
	span := ctx.Value("opentracing-span").(opentracing.Span)
	child := tracer.StartSpan(opName, ext.RPCServerOption(span.Context()))
	return child
}

// StartChildSpanFromContext starts a child span from span within the supplied context, if available.
func StartChildSpanFromContext(ctx context.Context, opName string) opentracing.Span {
	if ctx.Value("opentracing-span") == nil {
		return tracer.StartSpan(opName, ext.RPCServerOption(nil))
	}
	parent := ctx.Value("opentracing-span").(opentracing.Span)
	child := tracer.StartSpan(opName, opentracing.ChildOf(parent.Context()))
	return child
}

// StartSpanFromContextWithLogEvent starts span from context with logevent
func StartSpanFromContextWithLogEvent(ctx context.Context, opName string, logStatement string) opentracing.Span {
	span := ctx.Value("opentracing-span").(opentracing.Span)
	child := tracer.StartSpan(opName, ext.RPCServerOption(span.Context()))
	child.LogEvent(logStatement)
	return child
}

// CloseSpan logs event finishes span.
func CloseSpan(span opentracing.Span, event string) {
	span.LogEvent(event)
	span.Finish()
}

// LogEventToOngoingSpan extracts span from context and adds LogEvent
func LogEventToOngoingSpan(ctx context.Context, logMessage string) {
	if ctx.Value("opentracing-span") != nil {
		ctx.Value("opentracing-span").(opentracing.Span).LogEvent(logMessage)
	}
}

// UpdateContext updates the supplied context with the supplied span.
func UpdateContext(ctx context.Context, span opentracing.Span) context.Context {
	return context.WithValue(ctx, "opentracing-span", span)
}

duplicate `zuul` key in file `support/edge-server/src/main/resources/application.yml`

diff --git a/support/edge-server/src/main/resources/application.yml b/support/edge-server/src/main/resources/application.yml
index e8ad250..ac54d54 100644
--- a/support/edge-server/src/main/resources/application.yml
+++ b/support/edge-server/src/main/resources/application.yml
@@ -87,20 +87,6 @@ endpoints:
   health:
     sensitive: false

-zuul:
-  ignoredServices: "*"
-  prefix: /api
-  routes:
-#    securedaccountservice:
-#      path: /secured/account/**
-#      url:  http://securityservice:6666/account
-    accountservice:
-      path: /accounts/**
-      url:  http://accountservice:6767/accounts
-    accountservicehealth:
-      path: /accounts/health
-      url:  http://accountservice:6767/health
-
 logging:
   level:
     ROOT: DEBUG

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.