Stateful Application Server_JRubyConf13_Lukas Rieder

1,335 views
1,225 views

Published on

After more than one year of development, Wooga is heading for the global launch of its game "Kingsbridge"!

This is the first game at Wooga with a backend written in JRuby!

The talk includes an introduction to the problems that were solved by choosing a stateful applicaton server.

I will explain constraints, benefits and obvious differences to traditional database backed application servers.

Safely sharing state in a concurrent environment using JRuby
Using Java concurrency utils in JRuby
Sample problems solved, backed up with code
Practical tips for capacity planning

Published in: Technology, Business
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,335
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
15
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Stateful Application Server_JRubyConf13_Lukas Rieder

  1. 1. stateful application server
  2. 2. Hi I’m Lukas @Overbryd
  3. 3. Working @Wooga
  4. 4. stateful application server
  5. 5. database based system
  6. 6. app app app load db clients
  7. 7. stateful system
  8. 8. app app app client
  9. 9. app app app dns load clients
  10. 10. every server is equal
  11. 11. app nginx jvm redis ssd
  12. 12. state
  13. 13. jvm {}
  14. 14. ‣ SessionManager ‣ Session ‣ Resources ‣ Items ‣ Quests ‣ Payments ...
  15. 15. the hard part
  16. 16. one place at a time
  17. 17. easy with one server, but how to scale out?
  18. 18. sharding!
  19. 19. “static sharding” shard = facebook_id % shards
  20. 20. raise Invalid, “wrong shard” unless Shard.valid?(facebook_id)
  21. 21. concurrency
  22. 22. jvm http threads sessions ticker thread worker threads
  23. 23. the hard part
  24. 24. serialized access to a session
  25. 25. easy for low contention like a single session
  26. 26. class Session attr_reader :lock def initialize @lock = Mutex.new end # ... end session.lock.synchronize do session.foo end
  27. 27. harder for high contention like the SessionManager
  28. 28. class SessionManager @current = ConcurrentHashMap.new def self.get(id) raise WrongShard unless Shard.valid?(id) unless session = @current.get(id) new_session = create(id) unless session = @current.put_if_absent(id, new_session) session = new_session end end session end end
  29. 29. t1 t2 {} S S
  30. 30. t1 t2 {} S S
  31. 31. t1 t2 {} S S session = @current.get(id) # => nil session = @current.get(id) # => nil
  32. 32. S2 t1 t2 {} S S
  33. 33. S2 t1 t2 {} S S S1 S2
  34. 34. S2 t1 t2 {} S S S1 S2 S2
  35. 35. S2 t1 t2 {} S S S1 S2 S2 S2
  36. 36. S2 t1 t2 {} S S S1 S2 S2 S2
  37. 37. S2 new_session = create(id) unless session = @current.put_if_absent(id, new_session) # => nil session = new_session # => #<Session:0x2> end t1 new_session = create(id) unless session = @current.put_if_absent(id, new_session) # => #<Session:0x2> t2 {} S S S1 S2 S2 S2
  38. 38. deployment
  39. 39. the hard part
  40. 40. one place at a time
  41. 41. handover
  42. 42. app nginx jvm1 jvm2 S1
  43. 43. app nginx jvm1 jvm2 S1
  44. 44. app nginx jvm1 jvm2 S1
  45. 45. app nginx jvm2 S1
  46. 46. global state
  47. 47. weird problem when handling sharded state
  48. 48. even weirder when every machine should be equal
  49. 49. app nginx jvm redis ssd
  50. 50. global data is kept local
  51. 51. populates via UPD broadcast
  52. 52. not “a huge” problem if stale
  53. 53. last write wins self healing
  54. 54. class Broadcast def self.spawn_listener Thread.new do socket = wait_until_socket_bind loop do if @stop_listener socket.close return end message, from = socket.recvfrom(1024) handle_message(message) end end end end
  55. 55. appjvm redis appjvm redis internal network jvm
  56. 56. appjvm redis appjvm redis internal network jvm
  57. 57. appjvm redis appjvm redis internal network jvm

×