Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Gilmour: GopherCon London

Gilmour: GopherCon London

Piyush Verma

August 19, 2016
Tweet

More Decks by Piyush Verma

Other Decks in Programming

Transcript

  1. SOA (VS SERVERS) WHAT ARE SERVICES? ▸ Logical Entities. ▸

    Independent. ▸ Comprised of more services. ▸ Multiple instances. ▸ Scalable. ▸ Flexible.
  2. WHODUNNIT WHY ARE SERVICES? ▸ Software Problem ▸ Heterogeneity ▸

    Flexibility ▸ Scalability ▸ Management Problem ▸ Authority ▸ Responsibility.
  3. REQUEST req := g.NewRequest(“message.echo”) data := G.NewMessage().SetData("hello?") resp, err :=

    req.Execute(data) fmt.Println("Echoclient: received", resp) g.ReplyTo(“message.echo", func(req *G.Request, resp *G.Message) { var msg string req.Data(&msg) //Parse data from incoming request. resp.SetData(“Pong") //Send response. }, opts) RECEIVER REQUEST
  4. ASYNC: SIGNALS AND SLOTS Slots Signal EVENT.POWER_UP EVENT.* EVENT.* GROUP:

    REVENUE FP SCALING PUSH MESSAGE SERVER ADS/ MARKETINGSERVER ANALYTICS/ LOGS BADGES/ UNLOCKS EVENT.* ADS/MARKETING GAME GILMOUR EVENT EVENT.BRIDGE_FALL FALL FROM BRIDGE FALL FROM BRIDGE FALL FROM BRIDGE GROUP: BRIDGE_FALL
  5. ASYNC: SLOTS g.Slot("example.log", func(req *G.Request) { var msg string req.Data(&msg)

    log.Println(req.Sender(), "->", msg) }) msg := G.NewMessage().SetData(“log message emitted”) g.Signal("example.log", msg) SIGNAL RECEIVER / SLOT
  6. ASYNC VS SYNC: WHAT TO USE WHEN? REQUEST-RESPONSE ▸ Confirmed

    delivery. ▸ Response or Error; Guaranteed. ▸ HTTP-like. ▸ Sender responsible for Errors.
  7. ASYNC VS SYNC: WHAT TO USE WHEN? SIGNAL-SLOTS ▸ Broadcasting.

    ▸ Wildcard topics. ▸ UDP-Like. ▸ Ok with unreliable delivery. ▸ Receiver responsible for Errors.
  8. ERRORS: REQUEST - RESPONSE CALLER SERVICE HELLO? WRONG NUMBER SENDER_ID

    CODE ERROR REPORTER HYSTRIX PAGER DUTY HONEY BADGER EMAIL ALERTS
  9. ERRORS: SIGNAL - SLOTS WEB GILMOUR EMAIL NOTIFIER SMS NOTIFIER

    PUSH MESSAGE Slots Signal PAGER DUTY HONEY BADGER EMAIL ALERTS ERROR REPORTER GILMOUR.ERROR
  10. LOAD BALANCING - TYPICAL NOTIFICATION SERVER 1 REPLICATED LOAD BALANCER

    X.Y.Y.Z? CALLER SERVICE REGISTER I, AM HEALTHY? NOTIFICATION SERVER 2 NOTIFICATION SERVER 3
  11. LOAD BALANCING : GILMOUR NOTIFICATION SERVER 2 GILMOUR MANAGER.NOTIFICATION NOTIFICATION

    SERVER 1 NOTIFICATION SERVER 3 MANAGER.NOTIFICATION MANAGER.NOTIFICATION CALLER SERVICE MANAGER.NOTIFICATION {“NOTIFICATION”: “DATA”}
  12. DISCOVERY AND LOAD BALANCING LOOK MA, NO SERVICE DISCOVERY ▸

    Gilmour works on Subscriber Publisher. ▸ No querying discovery process. ▸ Call service and not servers.
  13. DISCOVERY AND LOAD BALANCING LOOK MA, NO LOAD BALANCING ▸

    Has Capacity, Will Serve. ▸ Message delivered to one and all. ▸ Fittest node acquires lock first.
  14. GILMOUR ERRORS ERROR DETECTION ▸ Timeout: ▸ Server-side - Execution

    expired. ▸ Client-side - Response too late. ▸ Confirm Subscribers or 404. ▸ Distinguished network failures.
  15. GILMOUR ERRORS ERROR HANDLING ▸ Ignore ▸ Publish ▸ Queue

    func main() { redis := backends.MakeRedis("127.0.0.1:6379", "pass") g := G.Get(redis) //g.SetErrorPolicy(protocol.ErrorPolicyQueue) //g.SetErrorPolicy(protocol.ErrorPolicyIgnore) g.SetErrorPolicy(protocol.ErrorPolicyPublish) }
  16. ERRORS: type GilmourError interface { Marshal() ([]byte, error) GetTopic() string

    GetSender() string GetCode() int GetTimestamp() string GetRequestData() string GetUserData() string GetBacktrace() interface{} } type gError struct { topic string //topic to which the request was sent requestData string //request payload userData string //implementation dependent information sender string //sender from the request timestamp string //timestamp of error backtrace interface{} //backtrace of the error code int //response code (non-200) } ERROR IMPLEMENTATION
  17. OPS: MONITORING SERVICES ▸ Are the services servicing? ▸ Do

    services have spare capacity? ▸ Do services respond in time? ▸ Health Bulletin: github.com/gilmour-libs/health-bulletin
  18. OPS: MONITORING Feb 23 12:25:14 qa-next-backend-manager0.datascale.io gilmour_health: D, [2016-02-23T06:55:12.930435 #22111]

    DEBUG -- : Ensuring topics have at least one subscriber Feb 23 12:25:14 qa-next-backend-manager0.datascale.io gilmour_health: D, [2016-02-23T06:55:12.931160 #22111] DEBUG -- : Ensuring that gilmour servers respond to health ping Feb 23 12:26:14 qa-next-backend-manager0.datascale.io backend_manager: D, [2016-02-23T06:56:12.932775 #9605] DEBUG -- : Executing handler for gilmour.health.ip-10-0-0-146-pid-9605-uuid-9d0484dd-08e5-4ec3- a3e4-9a109634712b from 2881867d41f24228b462b9eff0b7e88e 2016-04-03 00:06:56 d0e4ea929645600e2fa97657091613a4 -> Cleared VPC jenkins-backend-manager-pipeline-qa-17 2016-04-03 00:06:56 d0e4ea929645600e2fa97657091613a4 -> Clearing databag customer_jenkins-backend-manager- pipeline-qa-17_config::vpc_config 2016-04-03 00:06:57 d0e4ea929645600e2fa97657091613a4 -> Deleted data_bag[customer_jenkins-backend-manager- pipeline-qa-17_config] 2016-04-03 00:06:57 d0e4ea929645600e2fa97657091613a4 -> Clearing DNS entries 2016-04-03 00:07:00 d0e4ea929645600e2fa97657091613a4 -> Cleaning Chef environment 2016-04-03 00:07:01 d0e4ea929645600e2fa97657091613a4 -> Deleted customer_jenkins-backend-manager-pipeline- qa-17 REQUEST LOGGING
  19. COMPOSITION ▸ compose - service1 | service2 | composition3 ▸

    andand - service1 && service2 && composition3 ▸ oror - service1 || composition2 || service3 ▸ batch ▸ (service1; service2; service3) > out ▸ service1; composition2; service3 > out ▸ parallel ▸ lambda functions
  20. COMPOSITION popular := g.NewParallel( g.NewRequestComposition("example.popular3"), g.NewRequestComposition("example.popular4"), ) batch := g.NewPipe(

    g.NewRequestComposition("example.fetch"), g.NewRequestComposition("example.words"), g.NewRequestComposition("example.count"), popular, ) data := G.NewMessage() data.SetData("https://s3.amazonaws.com/ds-data-sample/test.txt") msg := <-batch.Execute(data)
  21. COMPOSITION popular := g.NewParallel( g.NewRequestComposition("example.popular3"), g.NewRequestComposition(“example.popular4"), g.NewRequestComposition("example.popular5"), ) batch :=

    g.NewPipe( g.NewRequestComposition("example.fetch"), g.NewRequestComposition("example.words"), g.NewRequestComposition("example.stopfilter"), g.NewRequestComposition("example.count"), popular, &MyComposer{}, ) 
 data := G.NewMessage() data.SetData("https://s3.amazonaws.com/ds-data-sample/test.txt") msg := <-batch.Execute(data)
  22. COMPOSITION batch := e.NewPipe( e.NewRequest("weather.fetch"), e.NewRequest("weather.group"), e.NewParallel( e.NewPipe( e.NewLambda(monthLambda("jan")), e.NewParallel(

    e.NewRequest("weather.min"), e.NewRequest("weather.max"), ), ), e.NewPipe( e.NewLambda(monthLambda("feb")), e.NewParallel( e.NewRequest("weather.min"), e.NewRequest("weather.max"), ), ), ), )
  23. EXAMPLES: POPULAR WORD COUNT ▸ Given ▸ A S3 URL

    pointing to a file that has (lot of) random text. ▸ Goal ▸ Eliminate stop words from the file. ▸ Find most popular 3, 4, and 5 letter words. ▸ Find these in parallel.
  24. EXAMPLES: WEATHER AGGREGATION ▸ Output ▸ Popular 3 letter words:

    [way, for] ▸ Popular 4 letter words: [Text, copy] ▸ Popular 5 letter words: [Blind, blind]
  25. GILMOUR RECAP ▸ No Load Balancer ▸ No Service Discovery

    ▸ Signal, Slots. ▸ Broadcast using Wildcard Topics. ▸ Exclusion groups. ▸ Sync - Request, Reply ▸ Error and Health Monitoring - HealthBulletin. ▸ Failure Detection ▸ Composition - Real micro-services. ▸ No message persistence.
  26. GILMOUR CREDITS & LINKS ▸ Aditya Godbole ▸ Amit Sethi

    ▸ Mohan Dutt ▸ Poorva Mahajan ▸ Datascale.IO datascale.io ▸ Repository github.com/gilmour-libs