Translate

viernes, 2 de septiembre de 2022

[O’Reilly eBook] Load Balancing in the Cloud

 

 

Migrating to software load balancing doesn’t mean you have to own and operate all the software yourself. Cloud services provide an alternative way to consume software infrastructure.

Cloud services greatly reduce the cost and hassle of provisioning redundant equipment and load balancers and enable you to handle separate network, application, and client-side loads. This ebook by author Derek DeJonghe is a practical guide to load balancing services in the cloud, including the NGINX software load balancer with AWS Network Load Balancer (AWS NLB) and global load balancing with Amazon Route 53.

Download this ebook to:

  • Learn how load balancing capabilities have evolved in just the past few years
  • Explore the features, portability, scaling, and autoscaling capabilities of the NGINX software load balancer
  • Understand the advantages of using AWS NLB with NGINX Plus, and learn ways to monitor AWS NLB as well as NGINX and NGINX Plus deployments
  • Use infrastructure management best practices to scale, secure, and monitor your application
 
 
 
Related Resources
 

NGINX: High-Performance Load Balancing
Learn the essential elements and best practices for load balancing your applications with NGINX and NGINX Plus in this on-demand webinar.

 

Deploying NGINX Plus and AWS Network Load Balancer
Learn about the all-active, high availability NGINX solution that takes advantage of the AWS NLB to improve the performance, reliability, and scalability of web applications.

 
twitterIcon.pngyoutubeIcon.pnglinkedinIcon.png
nginx-favicon.png
Contact us
nginx-inquiries@nginx.com
1-800-915-9122
© 2022 F5, Inc. ⋅ 795 Folsom Street, San Francisco, CA 94107

jueves, 1 de septiembre de 2022

Mónadas en Cats parte 22

El poder de la mónada State proviene de la combinación de instancias. Los métodos map y flatMap enhebran el estado de una instancia a otra. Cada instancia individual representa una transformación de estado atómico, y su combinación representa una secuencia completa de cambios:

val step1 = State[Int, String]{ num =>

   val ans = num + 1

   (ans, s"Result of step1: $ans")

}

val step2 = State[Int, String]{ num =>

val ans = num * 2

(ans, s"Result of step2: $ans")

}

val both = for {

   a <- step1

   b <- step2

} yield (a, b)

val (state, result) = both.run(20).value

// state: Int = 42

// result: (String, String) = ("Result of step1: 21", "Result of step2 : 42")

El estado final es el resultado de aplicar ambas transformaciones en secuencia. El estado se entrelaza paso a paso, aunque no interactuamos con él.

El modelo general para usar la mónada State es representar cada paso de un cálculo como una instancia y componer los pasos usando los operadores de mónada estándar. Cats proporciona varios constructores de conveniencia para crear pasos primitivos:

• get extrae el estado como resultado;

• set actualiza el estado y devuelve unit como resultado;

• pure ignora el estado y devuelve un resultado proporcionado;

• inspect extrae el estado a través de una función de transformación;

• modify actualiza el estado utilizando una función de actualización.


val getDemo = State.get[Int]

// getDemo: State[Int, Int] = cats.data.IndexedStateT@796af713

getDemo.run(10).value

// res1: (Int, Int) = (10, 10)

val setDemo = State.set[Int](30)

// setDemo: State[Int, Unit] = cats.data.IndexedStateT@f9e66fa

setDemo.run(10).value

// res2: (Int, Unit) = (30, ())

val pureDemo = State.pure[Int, String]("Result")

// pureDemo: State[Int, String] = cats.data.IndexedStateT@439e3ee4

pureDemo.run(10).value

// res3: (Int, String) = (10, "Result")

val inspectDemo = State.inspect[Int, String](x => s"${x}!")

// inspectDemo: State[Int, String] = cats.data.IndexedStateT@77263be4

inspectDemo.run(10).value

// res4: (Int, String) = (10, "10!")

val modifyDemo = State.modify[Int](_ + 1)

// modifyDemo: State[Int, Unit] = cats.data.IndexedStateT@44ddcbfc

modifyDemo.run(10).value

// res5: (Int, Unit) = (11, ())


Podemos ensamblar estos bloques de construcción usando una comprensión. Por lo general, ignoramos el resultado de las etapas intermedias que solo representan transformaciones en el estado:


import cats.data.State

import State._

val program: State[Int, (Int, Int, Int)] = for {

a <- get[Int]

_ <- set[Int](a + 1)

b <- get[Int]

_ <- modify[Int](_ + 1)

c <- inspect[Int, Int](_ * 1000)

} yield (a, b, c)

// program: State[Int, (Int, Int, Int)] = cats.data.IndexedStateT@42c9d44a

val (state, result) = program.run(1).value

// state: Int = 3

// result: (Int, Int, Int) = (1, 2, 3000)

sábado, 27 de agosto de 2022

Enums en Scala 3


Todavia no estoy a full con todos los cambios en scala 3. Pero sin duda algo que me llamaba la atención es que scala 2 no soporte enums. Si necesitabamos algo similar teniamos que hacer lo siguiente: 


object Permissions extends Enumeration {

  val READ, WRITE, EXEC, NONE = Value

}


Pero esto ya no es más así y ahora tenemos enums : 


enum Permissions {

    case READ, WRITE, EXEC

}

Y para utilizarlo hacemos : 


val read: Permissions = Permissions.READ


A la vez podemos utilizar toda la potencia de los enums como en java, por ejemplo tener argumentos : 


enum PermissionsWithBits(bits: Int) {

    case READ extends PermissionsWithBits(4) // binary 100

    case WRITE extends PermissionsWithBits(2) // binary 010

    case EXEC extends PermissionsWithBits(1) // binary 001

    case NONE extends PermissionsWithBits(0)

//Podemos tener metodos : 

   def toHex: String = Integer.toHexString(bits) // the java way of impl

}


Como es de esperar tambien tenemos un conjunto de propiedades que nos brinda el lenguaje, similares a java : 


val indexOfRead = Permissions.READ.ordinal //saber el orden

val allPermissions = Permissions.values // Todos los valores

val readPermission = Permissions.valueOf("READ") //Pasar de string a enum

viernes, 26 de agosto de 2022

Migrar a la nube garantiza agilidad y seguridad para tus datos

 

martes, 23 de agosto de 2022

Modificadores en Kotlin


En Kotlin, como en Java, puede declarar una clase abstracta y no se pueden crear instancias de dichas clases. Una clase abstracta generalmente contiene miembros abstractos que no tienen implementaciones y deben anularse en las subclases. Los miembros abstractos siempre están abiertos, por lo que no necesita usar un modificador de apertura explícito:

abstract class Animated {

    abstract fun animate()

    open fun stopAnimating() { }

    fun animateTwice() { }

}

Veamos los diferentes tipos de modificadores: 

  • final: esta por defecto en las clases y no se puede sobreescribir el método
  • open: no esta por defecto las clases salvo que sea un método abstracto o interfaz y se puede sobreescribir
  • abstract: se debe sobreescribir y puede ser usado solo en clases abstractas
  • override: indica que estamos sobreescribiendo un método y es open por defecto salvo que le pongamos final. 

En las interfaces, no se usa final, open o abstract. Un miembro en una interfaz siempre está abierto; no puedes declararlo como definitivo o final. Es abstracto si no tiene cuerpo, pero no se requiere la palabra clave.




lunes, 22 de agosto de 2022

Sobre escribir métodos en Kotlin


Java permite crear subclases de cualquier clase y anular cualquier método, a menos que se haya marcado explícitamente con la palabra clave final. Esto a menudo es conveniente, pero también es problemático.

El llamado problema de la clase base frágil ocurre cuando las modificaciones de una clase base pueden causar un comportamiento incorrecto de las subclases porque el código modificado de la clase base ya no coincide con los supuestos en sus subclases. Si la clase no proporciona reglas exactas sobre cómo debe subclasificarse (qué métodos se supone que deben anularse y cómo), los clientes corren el riesgo de anular los métodos de una manera que el autor de la clase base no esperaba. Debido a que es imposible analizar todas las subclases, la clase base es "frágil" en el sentido de que cualquier cambio en ella puede provocar cambios inesperados en el comportamiento de las subclases.

Kotlin sigue la filosofía "diseñe y documente para herencia o, de lo contrario, prohíbalo". Mientras que las clases y los métodos de Java están abiertos de forma predeterminada, los de Kotlin son definitivos de forma predeterminada. Si desea permitir la creación de subclases de una clase, debe marcar la clase con el modificador open. Además, debe agregar el modificador open a cada propiedad o método que se pueda anular.


open class RichButton : Clickable {

    fun disable() {}

    open fun animate() {}

    override fun click() {}

}


Si anula un miembro de una clase o interfaz base, el miembro anulado también se abrirá de forma predeterminada. Si desea cambiar esto y prohibir que las subclases de su clase anulen su implementación, puede marcar explícitamente el miembro anulado como final:


open class RichButton : Clickable {

    final override fun click() {}

}



viernes, 19 de agosto de 2022

Kubernetes: El futuro de los datos está en los contenedores


Cursos Gugler!!

 

 PRENSA GUGLER  LAB 2022

  NOTICIAS ACTUALES

informacion  OFERTA ACADÉMICA


Estimado Goette Emanuel :

 Se encuentran abiertas las inscripciones para el segundo cuatrimestre del año 2022, para todas las capacitaciones dictadas por el Laboratorio de Investigación Gugler. Podés asegurar tu lugar en el curso y comisión que desees !!!.

Las clases inician:

  • Martes 30/08 , Miércoles 31/08, Jueves 01/09 o Sábado 03/09, según el curso que elegiste

 

Inscribirteclic aquí

Cursos, Horarios y comisionesclic aquí.

 

 

Dictamos nuestros cursos en la Facultad de Ciencia y Tecnología, perteneciente a la Universidad Autónoma de Entre Ríos. En nuestro portafolio de capacitación encontrarás:

MODALIDAD PRESENCIAL

  • Cursos de Sistemas Operativos:
    Administración GNU/Linux.
     
  • Cursos de Programación:
    Programación en Python.
      
  • Cursos de Mantenimiento/Reparación:
    Reparación y Mantenimiento de PC.

 MODALIDAD DISTANCIA

  • Cursos de Programación:
    Programación en PHP.
    Programación en Java.
    Programación web frontend
informacion   MÁS INFORMACIÓN 

informacion LABORATORIO DE INVESTIGACIÓN GUGLER

Si deseas comunicarte con nosotros, te recordamos que podes hacerlo a través de los siguientes portales, en los cuales encontrarás información sobre Gugler.

TEL: (0343) - 4975066 Interno 119

Sitio Oficial:  www.gugler.com.ar

Campus:  campusvirtual.gugler.com.ar

Sistema de Gestión Cursos:  sgc.gugler.com.ar

Sistema de Gestión Cursos Móvil: Aquí 

Sistema de Documentación:  sgd.gugler.com.ar

Sistema de Validación:  giua.gugler.com.ar

                   Twitter                Facebook

Laboratorio Gugler

partir del 2012, la Facultad de Ciencia y Tecnología nos declaro:  "Laboratorio de Investigación".

 

El laboratorio ha ampliado las incumbencias de Gugler, ya que además de la capacitación, la promoción y difusión del software libre, ahora abarcará actividades como publicaciones y proyectos de investigación, así como también el dictado y participación en conferencias o exposiciones de ámbitos académicos y científicos.

 

Ante cualquier duda comunicarse con nosotros a gugler_contacto@uader.edu.ar

GUGLER PRESS

 

[O'Reilly eBook] The Enterprise Path to Service Mesh Architectures

 

 
 
 

Whether you’re preparing to build microservices-based, cloud-native applications, or looking to modernize your existing set of application services, you may want to consider using a service mesh. The more services your enterprise manages, the more intense any headaches you encounter are likely to be. This practical ebook explains how a service mesh provides a configurable infrastructure layer that makes service-to-service communication flexible, reliable, and fast.

Download this ebook to learn:

  • Service mesh concepts, architecture, and components, such as data planes and control planes
  • How a service mesh provides visibility, traffic management, resiliency, and security control for distributed application services, and the differences among service meshes and service mesh components
  • How service meshes compare to related technologies such as container orchestrators, API gateways, and client-side libraries
  • Practical steps for service mesh adoption, customization, deployment, and integration
 
 
 
Related Resources
 

What Is a Service Mesh?
A service mesh is a configurable infrastructure layer for microservices application that makes communication flexible, reliable, and fast. Learn more in this blog. 

 

NGINX, Istio, and the Move to Microservices and Service Mesh
This webinar discusses microservices architectures, and describes how NGINX is emerging as a widely used microservices hub, as a Kubernetes Ingress controller, and as a sidecar proxy in the Istio service mesh.

 
twitterIcon.pngyoutubeIcon.pnglinkedinIcon.png
nginx-favicon.png
Contact us
nginx-inquiries@nginx.com
1-800-915-9122
© 2022 F5, Inc. ⋅ 795 Folsom Street, San Francisco, CA 94107

miércoles, 17 de agosto de 2022

Mónadas en Cats parte 22

Como hemos visto con Reader y Writer, el poder de la mónada State proviene de la combinación de instancias. Los métodos map y flatMap enhebran el estado de una instancia a otra. Cada instancia individual representa una transformación de estado atómico, y su combinación representa una secuencia completa de cambios:

val step1 = State[Int, String]{ num =>

    val ans = num + 1

    (ans, s"Result of step1: $ans")

}

val step2 = State[Int, String]{ num =>

    val ans = num * 2

    (ans, s"Result of step2: $ans")

}

val both = for {

    a <- step1

    b <- step2

} yield (a, b)

val (state, result) = both.run(20).value

// state: Int = 42

// result: (String, String) = ("Result of step1: 21", "Result of step2: 42")


Como puedes ver, en este ejemplo el estado final es el resultado de aplicar ambas transformaciones en secuencia. El estado se entrelaza paso a paso, aunque no interactuamos con él. El modelo general para usar la mónada de estado es representar cada paso de un cálculo como una instancia y componer los pasos usando los operadores de mónada estándar. Cats proporciona varios constructores de conveniencia para crear pasos primitivos:

  • get extrae el estado como resultado;
  • set actualiza el estado y devuelve la unidad como resultado;
  • pure ignora el estado y devuelve un resultado proporcionado;
  • inspect extrae el estado a través de una función de transformación;
  • modify actualiza el estado utilizando una función de actualización.

val getDemo = State.get[Int]
// getDemo: State[Int, Int] = cats.data.IndexedStateT@796af713
getDemo.run(10).value
// res1: (Int, Int) = (10, 10)
val setDemo = State.set[Int](30)
// setDemo: State[Int, Unit] = cats.data.IndexedStateT@f9e66fa
setDemo.run(10).value
// res2: (Int, Unit) = (30, ())
val pureDemo = State.pure[Int, String]("Result")
// pureDemo: State[Int, String] = cats.data.IndexedStateT@439e3ee4
pureDemo.run(10).value
// res3: (Int, String) = (10, "Result")
val inspectDemo = State.inspect[Int, String](x => s"${x}!")
// inspectDemo: State[Int, String] = cats.data.IndexedStateT@77263be4
inspectDemo.run(10).value
// res4: (Int, String) = (10, "10!")
val modifyDemo = State.modify[Int](_ + 1)
// modifyDemo: State[Int, Unit] = cats.data.IndexedStateT@44ddcbfc
modifyDemo.run(10).value
// res5: (Int, Unit) = (11, ())

Podemos ensamblar estos bloques de construcción usando una comprensión. Por lo general, ignoramos el resultado de las etapas intermedias que solo representan transformaciones en el estado:

import cats.data.State
import State._
val program: State[Int, (Int, Int, Int)] = for {
a <- get[Int]
_ <- set[Int](a + 1)
b <- get[Int]
_ <- modify[Int](_ + 1)
c <- inspect[Int, Int](_ * 1000)
} yield (a, b, c)
// program: State[Int, (Int, Int, Int)] = cats.data.
IndexedStateT@42c9d44a
val (state, result) = program.run(1).value
// state: Int = 3
// result: (Int, Int, Int) = (1, 2, 3000)

sábado, 13 de agosto de 2022

Interfaces en Kotlin


Las interfaces de Kotlin son similares a las de Java 8: pueden contener definiciones de métodos abstractos, así como implementaciones de métodos no abstractos (similares a los métodos predeterminados de Java 8), pero no pueden contener ningún estado. Para declarar una interfaz en Kotlin, se usa la palabra clave de interface en lugar de class.


interface Clickable {

    fun click()

}


Esto declara una interfaz con un solo método abstracto llamado clic. Todas las clases no abstractas que implementan la interfaz deben proporcionar una implementación de este método. 

class Button : Clickable { override fun click() = println("I was clicked") } 

>>> Button().click() 

I was clicked


Kotlin usa los dos puntos después del nombre de la clase para reemplazar las palabras clave extends e implements que se usan en Java. Como en Java, una clase puede implementar tantas interfaces como quiera, pero solo puede extender una clase.

El modificador override, similar a la anotación @Override en Java, se utiliza para marcar métodos y propiedades que anulan los de la superclase o la interfaz. A diferencia de Java, el uso del modificador de anulación es obligatorio en Kotlin. Esto le evita anular accidentalmente un método si se agrega después de escribir su implementación; su código no se compilará a menos que marque explícitamente el método como anulado o le cambie el nombre.

Un método de interfaz puede tener una implementación predeterminada. A diferencia de Java 8, que requiere que marques tales implementaciones con la palabra clave predeterminada, Kotlin no tiene una anotación especial para tales métodos: solo proporcionas un cuerpo de método. Cambiemos la interfaz Clickable agregando un método con una implementación predeterminada


interface Clickable { 

  fun click() 

  fun showOff() = println("I'm clickable!") 

}


Si implementa esta interfaz, debe proporcionar una implementación para hacer clic. Puede redefinir el comportamiento del método showOff o puede omitirlo si está de acuerdo con el comportamiento predeterminado. Supongamos ahora que otra interfaz también define un método showOff y tiene la siguiente implementación para él.


interface Focusable {

    fun setFocus(b: Boolean) = println("I ${if (b) "got" else "lost"} focus.")

    fun showOff() = println("I'm focusable!")

}


¿Qué sucede si necesita implementar ambas interfaces en su clase? Cada uno de ellos contiene un método showOff con una implementación predeterminada; ¿Qué implementación gana? Ninguno de los dos gana. En su lugar, obtiene el siguiente error del compilador si no implementa showOff explícitamente


The class 'Button' must override public open fun showOff() because it inherits many implementations of it


El compilador de Kotlin te obliga a proporcionar tu propia implementación.


class Button : Clickable, Focusable { 

    override fun click() = println("I was clicked")

    override fun showOff() { 

        super<Clickable>.showOff()

        super<Focusable>.showOff() } 

}


La clase Button ahora implementa dos interfaces. Implementa showOff() llamando a ambas implementaciones que heredó de los supertipos. Para invocar una implementación heredada, usa la misma palabra clave que en Java: super. Pero la sintaxis para seleccionar una implementación específica es diferente. Mientras que en Java puede colocar el nombre del tipo base antes de la palabra clave super, como en Clickable.super.showOff(), en Kotlin coloca el nombre del tipo base entre paréntesis angulares: super<Clickable>.showOff().

Si solo necesita invocar una implementación heredada, puede escribir esto:


override fun showOff() = super.showOff()


Puede crear una instancia de esta clase y verificar que se pueden llamar todos los métodos heredados


fun main(args: Array) { 

    val button = Button() 

    button.showOff() 

    button.setFocus(true) 

    button.click() 

}


La implementación de setFocus se declara en la interfaz Focusable y se hereda automáticamente en la clase Button.   

viernes, 12 de agosto de 2022

Creando un web service REST con ZIO


 Vamos hacer un pequeño proyecto con ZIO, como para empezar. El "hola mundo" de toda la vida pero en un servicio REST. 

Antes de empezar vamos a hacer un proyecto con scala 3 con sbt : 


sbt new scala/scala3.g8


Luego agregamos las dependencias de zio, el build.sbt debe quedar así : 


scalaVersion := "3.1.2"

organization := "dev.zio"

name         := "zio-quickstart-restful-webservice"


libraryDependencies ++= Seq(

  "dev.zio"       %% "zio"            % "2.0.0",

  "dev.zio"       %% "zio-json"       % "0.3.0-RC10",

  "io.d11"        %% "zhttp"        % "2.0.0-RC10",

  "io.getquill"   %% "quill-zio"    % "4.2.0",

  "io.getquill"   %% "quill-jdbc-zio" % "4.2.0",

  "com.h2database" % "h2"             % "2.1.214"

)


Aclaro que tengo otras dependencias como la de base de dato que las voy a usar en proximos ejemplos. 

Y ahore si, hacemos el web service para nuestro "hola mundo" : 


package dev.zio.quickstart.greet


import zhttp.http._


object GreetingApp {

  def apply(): Http[Any, Nothing, Request, Response] =

    Http.collect[Request] {

      // GET /greet?name=:name

      case req@(Method.GET -> !! / "greet") if (req.url.queryParams.nonEmpty) =>

        Response.text(s"Hello ${req.url.queryParams("name").mkString(" and ")}!")


      // GET /greet

      case Method.GET -> !! / "greet" =>

        Response.text(s"Hello World!")


      // GET /greet/:name

      case Method.GET -> !! / "greet" / name =>

        Response.text(s"Hello $name!")

    }

}



Luego programamos el Main :


package dev.zio.quickstart


import dev.zio.quickstart.counter.CounterApp

import dev.zio.quickstart.download.DownloadApp

import dev.zio.quickstart.greet.GreetingApp

import dev.zio.quickstart.users.{InmemoryUserRepo, PersistentUserRepo, UserApp}

import zhttp.service.Server

import zio._


object MainApp extends ZIOAppDefault {

  def run =

    Server.start(

      port = 8999,

      http = GreetingApp() 

    ).provide(

      // An layer responsible for storing the state of the `counterApp`

      ZLayer.fromZIO(Ref.make(0)),

      

      // To use the persistence layer, provide the `PersistentUserRepo.layer` layer instead

      InmemoryUserRepo.layer

    )

}


Y listo!! Si vamos a http://localhost:8999/greet?name=Emanuel me va a saludar. 

Para correrlo lo pueden hacer con sbt run o con intellij corriendo el Main. 


Dejo el repo : 

https://github.com/emanuelpeg/zio-quickstart-restful-webservice

lunes, 8 de agosto de 2022

Primeros pasos con ZIO


Vamos hacer un pequeño proyecto con ZIO, como para empezar. El "hola mundo" de toda la vida. 

Antes de empezar vamos a hacer un proyecto con scala 3 con sbt : 

sbt new scala/scala3.g8

Luego agregamos las dependencias de zio, en este caso solo usaremos : 


libraryDependencies += "dev.zio" %% "zio" % "2.0.0"


De esta manera el archivo build.sbt será : 


val scala3Version = "3.1.3"


lazy val root = project

  .in(file("."))

  .settings(

    name := "zioHello",

    version := "0.1.0-SNAPSHOT",


    scalaVersion := scala3Version,

    libraryDependencies += "dev.zio" %% "zio" % "2.0.0",

    libraryDependencies += "org.scalameta" %% "munit" % "0.7.29" % Test

  )


Y luego vamos a hacer nuestro "hola mundo" en el archivo Main.scala : 


import zio._
import zio.Console._

object Main extends ZIOAppDefault :

  def run = myAppLogic

  val myAppLogic =
    for {
      _    <- printLine("Hola, como te llamas guapo?")
      nombre <- readLine
      _    <- printLine(s"Hola, ${nombre}, welcome to ZIO!")
    } yield ()


Y listo!!