Monday, November 18, 2019

Docker, Kubernetes, Microservices, and Domain Driven Design

I'm attending an excellent 2-day workshop ASP.NET Core, Docker on Azure and Azure Kubernetes Service - What You Need to Know Part 1 and Part 2, with
Michele Bustamente of Solliance at DevIntersection right now.

It's a deep dive and much of the hands-on content is going over my head. But I am really appreciating the context, motivation, and use cases described. If you get a chance to hear Michele Bustamente speak, take it.

I am no expert on these topics, and much of it is a real departure from common design patterns back when I was a System Architect.

Domain Driven Design (DDD) and Microservices seem to fit well when there is a need to scale out and provide capacity elasticity. So it ties with containers and orchestration. Here are some succinct statements that I wish someone had written down for me.

Glossary


  • Domain Driven Design - a design approach for software
  • Microservices - an implementation approach for software
  • Containers - lightweight virtualized application environments
    • implied is elasticity - add or remove containers as load changes
  • Docker - a container framework
  • Orchestration - management of containers, resources, and their relationships through elastic operations, i.e. adding or removing containers or resources
  • Kubernetes - a framework for orchestration
  • .NET Core - Microsoft's implementation of .NET that is containerizable - free, open-source, and cross-platform

Domain Driven Design


  • DDD carves up functionalities into "domains"
  • functionalities within a domain are highly interrelated
  • functionalities across domains are less related
  • each domain is designed and developed from end-to-end: Persistence to User Interface
  • DDD teams are cross functional: organizational domain expert, developer, architect, data engineer, devops, etc.
  • The goal of a domain team is to create a very clean, tight set of services within the domain
  • meeting this goal is easier due to the clear, focused scope of the domain
Although there is nothing in DDD that requires use of microservices, or any particular architecture, it naturally aligns with microservices.

Microservices

  • focused, lightweight applications that provide functionality over a network
  • agnostic of any particular technology, language or framework
  • align well with DDD
  • can be (easily?) containerized
  • a domain's functionality could be implemented as one or more microservices
  • microservices are meant to be independent, and decoupled from each other
    • however, there may be shared resources, such as a database

Containers & Docker

  • containers are lightweight virtualized operating system environments for applications
  • lightweight is achieved through
    • limited feature set (thus .Net Core rather than .Net)
    • shared image, i.e., operating system kernel, libraries and other dependencies
  • lightweight is important for elasticity - cheap to allocate and reclaim
  • Docker is a commonly used container framework

Orchestration & Kubernetes

  • Orchestration tasks
    • provisioning of new containers 
    • configuration of containers
      • locations of resources, such as storage
      • credentials for resources
      • common state across containers
    • load balancing
    • logging of orchestration activities, errors
    • decommissioning of containers, reclamation of resources

Related Concepts & Requirements

  • Agile 
    • this mentality seems to be a pre-requisite
  • Continuous Integration / Continuous Deployment
    • all the basics, but also the containers and orchestration
  • Eventual Consistency
    • relates to domains sharing resources across domains
    • one domain/microservice (A) might have high levels of writes, while another (B) might have high levels of reads. This could be architected as separate data stores, with A writes going to a write-optimized store, and changes being replicated (eventually) on B's read optimized store

Summary

The current use case is for high volume systems that must be elastic. But the idea of smaller, focused, agile, domain driven teams is compelling. With well-scoped smaller domains, it should easier to achieve smooth CI/CD, embrace re-factoring when necessary, stay focused on domain issues, and deliver high-quality software. As the tooling gets better, the overhead involved in containers, orchestration, and distributed microservice coordination should make this even more compelling.

Wednesday, January 30, 2019

The SwitchOffset Function




-- Database by Doug
-- Douglas Kline
-- 1/30/2019
-- the SwitchOffset function

-- how to use switchoffset 
-- function available beginning SQL 2008

-- see "Time Zones and DATETIMEOFFSET" video

-- an update to the previous video
-- thanks to a viewer who pointed this function out to me
-- you know who you are!

SELECT GETDATE() AS [now, somewhere]

-- my time zone is EST -05:00
-- the server is in the Azure US east data center (EST)

-- note that the GETDATE() returns the time GMT, i.e. -00:00
-- the returned time is 5 hours in the future (based on EST)

-- also note that GETDATE() does not contain the time zone,
-- it returns a datetime, which does not contain time zone information

SELECT SQL_VARIANT_PROPERTY(GETDATE(), 'BaseType')

-- you can the server datetime with time zone like this:

SELECT SYSDATETIMEOFFSET(), 
       SQL_VARIANT_PROPERTY(SYSDATETIMEOFFSET(), 'BaseType')

-- this result proves that Azure SQL returns UTC 00:00

-- my current database server happens to be
-- in the eastern time zone of the US, which is -05:00 UTC

-- so what is the actual time, in EST?

-- observe the difference between the following values

SELECT GETDATE()                                  AS [Azure datetime GMT],
       CAST (GETDATE() AS DATETIMEOFFSET)         AS [converted Azure datetime GMT],
       TODATETIMEOFFSET(GETDATE(), '-05:00')      AS [todatetimeoffset result EST], -- but note no hour change
       SYSDATETIMEOFFSET()                        AS [sysdatetimeoffset EST],   
       SWITCHOFFSET(SYSDATETIMEOFFSET(),'-05:00') AS [switchoffset] -- this is the right one

-- note that GETDATE() is not as accurate  
-- for a couple of reasons
-- fewer decimal points

-- but also 
-- datetimes' one-thousandths place is always 0, 3, or 7   
-- from doc'n "Rounded to increments of .000, .003, or .007 seconds"

-- so, before SWITCHOFFSET existed, ...

SELECT SWITCHOFFSET(SYSDATETIMEOFFSET(),'-05:00')                AS [EST the easy way],
       TODATETIMEOFFSET(DATEADD(HOUR, -5, SYSDATETIMEOFFSET()), '-05:00')  AS [EST the hard way]

-- so, thinking of a DATETIMEOFFSET data type as a complex object
-- with many different parts: year, month, day, hour, time zone, etc.
-- it looks like SWITCHOFFSET changes two things: time zone and hour

-- but let's say that my source datetimeoffset 
--   is near a time part boundary, 
--   for example, the end of the year

DECLARE @NewYearsEveEST AS DATETIMEOFFSET
DECLARE @NewYearsEveGMT AS DATETIMEOFFSET

SET  @NewYearsEveEST = DATETIMEOFFSETFROMPARTS(2019,12,31,23,50,0,0,-5,0,7)
SET  @NewYearsEveGMT = SWITCHOFFSET(@NewYearsEveEST,'+00:00')

SELECT   @NewYearsEveEST AS [NYEveEST], 
         @NewYearsEveGMT AS [NYEveGMT]

-- note that the year, month, day, hour, and time zone changed

-- in summary
-- SWITCHOFFSET is really helpful to have
-- simpler code, likely more reliable
-- use SYSDATETIMEOFFSET to get max precision w/Offset

-- Database by Doug
-- Douglas Kline
-- 1/30/2019
-- the SwitchOffset function


Followers