I attended UberConf in Denver, CO from 7/19 - 7/22. This was my first UberConf, but it will most likely not be my last. The conference itself was well organized, at a beautiful location, and had a ton of excellent content presented by professionals.
I attended the following sessions and added notes where I took them. The slides and audio are only made available to attendees so I will not be linking to them.
Wednesday
8:30 AM - Core Software Design Principles - Venkat Subramaniam
Good design makes future change easier
TDD as an opportunity to drive the design
DRY - Don't Repeat Yourself
- every bit of knowledge in a system should have a single unambiguous authoritative representation
- the real reason to create a better desing is that the future you will thank you
- code generator when same logic in multiple languages (e.g. Java & JavaScript) research
YAGNI - You Aren't Gonna Need It (yet)
- avoid writing any code you can
- make code you write as small as possible
- applies to systems also - minimal feature set first
SRP - Single Responsibility Principle
- it is cheaper/easier to change code that does one thing
- long methods
- no idea what it is doing
- hard to test
- fear of breaking -> duplication -> hard to reuse
- side effects
- lacks cohesion (cohesion = narrow, focused, does one thing well)
- high/tight coupling
- good design has high cohesion and low coupling
- SLAP - Single Level of Abstraction Principle
- long methods are not based on line of code
- long methods have multiple levels of abstraction
- do one task
- Compose method pattern
- tranform logic into a small number of intention-revealing steps at the same level of detail
- replace strings of if/then with functions the identify the high level purpose of the code
OCP - Open Closed Principle
- modules should be open for extension but closed for modification
- it is better to add new code rather than change existing code
- showed example that had high cohesion and low coupling by combining a copy constructor with clone
- prefer extension to inheritance
- only use inheritance when you care about substitutability (use inheritance to allow using base or inherited class)
- LSP - Liskov's Substitution Principle
- a derived class should require no more & promise no less than the base class
- a user should be able to use the derived class without knowing the difference
DIP - Dependency Inversion Principle
- a class should not depend directly on another concrete class
- low coupling - depend on few
- loose coupling - depend on an interface rather than a class
Knowledge of principles increases communication speed & design critique
10:30 AM - Microservices AntiPatterns - Mark Richards
Data-Driven migration anti-pattern
- migrating monlithic data to microservices and targeted DB
- data is a corporate asset, not an application asset
- migrations highly risky
- lessons learned can lead to splitting/joining services but that requires another DB migration
- only migrate functionality first, then after services mature and data is defined migrate the data
- Book recommendation -> Refactoring Databases (Addison Wesley)
All the world's a stage anti-pattern
- too much focus on tech & creation rather than business functionality
- architectural refactoring key point - minimize risk
- staging iterations minimize risk & are very important
- too many staging iterations are the anti-pattern
- focus on business functionality and deliver devops along with new features
- devops gets to learn with real services
Hop on the bus anti-pattern
- integration hub/middle wear
- negatives
- performance - adds extra call
- governance - any introduced business logic becomes an issue, do not access/change data
- development and testing - becomes much more complex, have to have hub in the loop
- less reliable and robust
- potential positives
- contract transformation - XML transform, XML -> JSON, etc
- but a microservice transform is a better solution
- or a service can expose different transformed endpoint
- service orchestration (need a conductor)
- service choreography (partners) is alternative
- integration hub can handle orchestration, has previous issue
- introduce a microservice that integrates other services (conglomerate)
- hide basic services with API layer
- protocol agnostic heterogeneous interoperability
- hitting 3rd party system
- integration hub, same issues again
- microservice gateway, dedicated to a specific system (recommends one gateway per request)
- hitting 3rd party system
- domain scoped integration hub
- narrow scope can prevent microservice explosion
- same issues as full hub, just smaller scope
- bounded context still larger because of integration hub
- contract transformation - XML transform, XML -> JSON, etc
Timeout anti-pattern
- using timeout values when communicating with remote service
- availability - accepting requests? easy
- responsiveness - service working effectively?
- timeout when service has completed work is fatal… work completed by response ignored
- decent timeout time ≈ max time under load * 2 <- but simple timeout is the anti-pattern
- circuit breaker pattern and dynamic timeout (using previous formula, but let it change for current load)
- monitors service
- simple heartbeat (+ easy, - ping only)
- synthetic transaction (+ simple and trend analysis, - extremely complex because every piece must be aware of what makes transaction synthetic)
- real-user monitoring (+ dynamic, - half open state)
- Recommended reading - Martin Fowler circuit breaker blog post
Reach-in reporting anti-pattern
- pulling data from each microservice or it's DB for reporting service
- integration patterns
- DB pull model
- reporting sensitive to schema changes
- removes ability for microservice to be independent
- HTTP pull model (using service itself for data)
- performance issues
- data volume issues
- timeliness of data
- batch pull method <- worst option
- reporting DB & batch aggregator
- still sensitive to DB schema changes, etc
- event based publishing
- logs based on reporting concerns
- data capture service listens for posts, potentially creates reports
- DB pull model
Self assessment workbooks in slides
1:00 PM - Angular 2 for Java Devs - Ben Ellington
Code in GitHub
Can write plain JavaScript, but Typescript is base language
- command line interface for Angular
- creation, scaffolding, build/test, lint/format
Application is a combination of component implementations, services and models
- component is both a class and a view
- pipe allows template enhancing
- directives is a class w/o a view
…src/app contains generated code
ng serve - starts app w/autoupdate
@Component annotations module declaration
- selector ->
in JavaScript - templateUrl -> points to .html template
- styleUrl -> points to .css
Observable at each end point
2:45 PM - Spring Boot & Beyond - Craig Walls
DevTools - Spring Boot plugin
- autodeploy on save (livereload browser plugin)
- remote debug stupid easy
- remote deployment and LiveReload also work together
Customization/Overriding default configuration
@Configuration annotated class
application.(properties/yaml) - recommends always using .yaml
message.properties
@ConfigurationProperties(prefix="greeting") to class, then add
class_name:
greeting: Message
to application.yaml
OR
use -Dclass_name.greeting="Message" on command line
Spring profiles - must use "---" to separate profiles (.yaml only)
---
spring:
profiles: production
class_name:
greeting: "Hi from production"
^ Can activate by exporting SPRING_PROFILE_ACTIVE or command line switches
Actuator customization
Custom counter
@Autowired
public Class(CounterService cs) {
this.cs = cs;
}
endpoint code
cs.increment
cs.decrement
Gauge customization (similar to above)
GaugeService gs
gs.submit("key", <double value>);
/info endpoint
Edit application.yaml
info:
example: string
-> system_name:port/info body will be
{ example: string }
Put banner.png in resources folder, makes ASCII art of image and shows it at startup
4:30 PM - Continuous Integration for Web & JavaScript Projects - Pratik Patel
Instanbul - JavaScript code coverage tool
WebPack - bundle, minify, etc … might be time to try it
Yellow Lab - analyzes page load, makes recommendations for improvement
speedgun.io - gathers/displays web performance data on a site
8:30 PM - Taking Command of the Command Line - Venkat Subramaniam
pushd & popd vs cd
pbcopy 4tw
jps -> java process listing
On Windows "tasklist" is similar to "ps"
"script" records window interaction Ctrl-D ends
Thursday
9:00 AM & 11:00 AM - Continuous Delivery for Architects - Neal Ford
Architecture is abstract until operationalized
Modern architecture view takes into account evolution of pieces and dependencies (updates, versions, etc)
Metrics & monitoring
- cyclomatic complexity
- finding 5 most complex methods in a code base can be highly insightful
- code varies by < 10 on cyclomatic complexity is desirable
- Java NCSS
- afferent/efferent coupling
- incoming connections -> afferent
- outgoing connections -> efferent (remember efferent like exit)
- radiators - run on every build and generate metrics
- Kiviat Graphs - SourceMonitor static analysis, creates graph with relative complexity
- toxicity chart - Erik Doernenburg - How toxic is your code? Creates graph with code "toxicity" ratings
- CC/LOC - cyclomatic complexity per line of code over time, recommends picking tool to give overall code complexity metric and graphing it over time
- probes - higher level abstracted views
- CKJM - link in slides, cyclomatic complexity as sum of all functions in class
- X-Ray - Eclipse plugin & other forms - visualize code size & dependencies
- ArgoUML
Types of coupling - wikipedia
Content coupling - one module modifies or relies on inner workings of another (rare, prevented by most languages)
Common coupling - two modules share the same global data
External coupling - two modules share an externally imposed data format, communication protocol, or device interface
Control coupling - one module controlling the flow of another by passing it information
Stamp coupling - multiple modules share a composite data structure and only use parts of it
Data coupling - coupling via values passed via function parameters
Message coupling - coupling via passed messages
^ spectrum slide for severity of coupling and definitions
Temporal/Transactional coupling - often overlooked refactoring issue
JDepend - gives numeric value for coupling
CodeCity - code analysis as 3D map
Deployment pipeline
Jenkins - leading open source automation server
GoCD - open source continuous delivery server from the ThoughtWorks folks
Spinnaker - Netflix created open source continuous delivery
Analysis tools
JarAnalyzer - Kirk Knoernschild
Structure 101 - pay tool, help eliminate cycles in code
JDepend - Dependency Cycle test - slide with unit test
Fallacies of distributed computing - truth from wikipedia
Release It! Book - was mentioned multiple times by different presenters
devopsbookmarks.com - well done list of links that can be searched with a number of different filters
Service based architecture is more common endpoint of monolithic evolution
Most enterprises end up with a hybrid
Build a number of larger services first
Inverse Conway Maneuver - build teams that look like the architecture you want
Continuous Delivery Maturity***
Feature toggles - allow constant deployment with ability to release with config/DB changes
temporary technical debt that MUST be removed ASAP
togglz.org
Friday
9:00 AM & 10:45 AM - Clojure Workshop - Ship & Ford
Runs on JVM (Clojure), JavaScript(ClojureScript), .Net(something?)
edn - data representation
Clojure syntax == edn + functional stuff
Multi-arity allows some functions to take different number of arguments
Namespaces are similar to Java packages, but clojure doesn't have class names
Java -> new Widget("red") rnd.nextInt()
Clojure -> (Widget. "red) (.nextInt rnd)
Java -> person.getAddress().getZip()
Clojure -> (.. person getAddress getZip)
-> vs ->>
component - lifecycle events for systems
Useful projects