Listen and Serve

Bạn có thể chạy máy chủ bằng net.Listener hoặc even http.Server .Phương thức khởi tạo máy chủ nên chạy cuối cùng thông qua hàm Run.

Phương thức phổ biến nhất mà các nhà phát triển Go đang sử dụng trên máy chủ của họ là chuyển địa chỉ mạng với dạng "hostname:ip". Với Iris, chúng ta sử dụng iris.Addr đó là kiểu iris.Runnner

// Listening on tcp with network address 0.0.0.0:8080
app.Run(iris.Addr(":8080"))

Đôi khi bạn đã có một máy chủ tiêu chuẩn net/http ở một nơi khác trong ứng dụng của mình và muốn sử dụng nó để phục vụ ứng dụng web Iris

// Same as before but using a custom http.Server which may being used somewhere else too
app.Run(iris.Server(&http.Server{Addr:":8080"}))

Cách sử dụng nâng cao nhất là tạo net.Listener tùy chình hoặc tiêu chuẩn và chuyển nó cho app.Run

// Using a custom net.Listener
l, err := net.Listen("tcp4", ":8080")
if err != nil {
    panic(err)
}
app.Run(iris.Listener(l))

Một ví dụ đầy đủ hơn, sử dụng tính năng unix-only sockets

package main

import (
    "os"
    "net"

    "github.com/kataras/iris/v12"
)

func main() {
    app := iris.New()

    // UNIX socket
    if errOs := os.Remove(socketFile); errOs != nil && !os.IsNotExist(errOs) {
        app.Logger().Fatal(errOs)
    }

    l, err := net.Listen("unix", socketFile)

    if err != nil {
        app.Logger().Fatal(err)
    }

    if err = os.Chmod(socketFile, mode); err != nil {
        app.Logger().Fatal(err)
    }

    app.Run(iris.Listener(l))
}

Máy chủ UNIX và BSD có thể tận dụng tính năng tái sử dụng cổng

package main

import (
    // Package tcplisten provides customizable TCP net.Listener with various
    // performance-related options:
    //
    //   - SO_REUSEPORT. This option allows linear scaling server performance
    //     on multi-CPU servers.
    //     See https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/ for details.
    //
    //   - TCP_DEFER_ACCEPT. This option expects the server reads from the accepted
    //     connection before writing to them.
    //
    //   - TCP_FASTOPEN. See https://lwn.net/Articles/508865/ for details.
    "github.com/valyala/tcplisten"

    "github.com/kataras/iris/v12"
)

// go get github.com/valyala/tcplisten
// go run main.go

func main() {
    app := iris.New()

    app.Get("/", func(ctx iris.Context) {
        ctx.HTML("<h1>Hello World!</h1>")
    })

    listenerCfg := tcplisten.Config{
        ReusePort:   true,
        DeferAccept: true,
        FastOpen:    true,
    }

    l, err := listenerCfg.NewListener("tcp", ":8080")
    if err != nil {
        app.Logger().Fatal(err)
    }

    app.Run(iris.Listener(l))
}

HTTP/2 and Secure

Nếu bạn đã signed file keys bạn có thể sử dụng iris.TLS để phân phát https dựa trên các khóa đã chứng thực đó

// TLS using files
app.Run(iris.TLS("127.0.0.1:443", "mycert.cert", "mykey.key"))

Phương thức bạn nên sử dụng khi ứng dụng của bạn sẵn sàng để sản xuất là iris.AutoTLS để khởi động máy chủ một cách an toàn tự động với các chứng nhận được cung cấp miễn phí bởi https://letsencrypt.org

// Automatic TLS
app.Run(iris.AutoTLS(":443", "example.com", "admin@example.com"))

Any iris.Runner

Có thể đôi khi bạn muốn một điều gì đó đặc biệt mà không phải là kiểu net.Listener. Bạn có thể làm điều đó bằng iris.Raw, nhưng bạn phải chịu trách nhiệm về phương thức đó

// Using any func() error,
// the responsibility of starting up a listener is up to you with this way,
// for the sake of simplicity we will use the
// ListenAndServe function of the `net/http` package.
app.Run(iris.Raw(&http.Server{Addr:":8080"}).ListenAndServe)

 


Cấu hình máy chủ

Tất cả các hình thức ở trên đang chấp nhận đối số cuối cùng là biến đổi (variadic argument)  của func(*iris.Supervisor). Điều này được sử dụng để thêm các cấu hình cho máy chủ cụ thể thông qua các chức năng đó.

Ví dụ chúng ta muốn thêm callback được kích hoạt sau khi máy chủ tắt.

app.Run(iris.Addr(":8080", func(h *iris.Supervisor) {
    h.RegisterOnShutdown(func() {
        println("server terminated")
    })
}))

Bạn thậm chí có thể làm điều đó trước phương thức app.Run, nhưng điểm khác biệt là các cấu hình máy chủ này sẽ được thực thi cho tất cả các máy chủ mà bạn có thể sử dụng để phục vụ ứng dụng web của mình (thông qua app.Newhost chúng ta sẽ thấy điều đó trong một phút)

app := iris.New()
app.ConfigureHost(func(h *iris.Supervisor) {
    h.RegisterOnShutdown(func() {
        println("server terminated")
    })
})
app.Run(iris.Addr(":8080"))

Truy cập vào tất cả các máy chủ phục vụ ứng dụng của bạn có thể được cung cấp bởi trường Application#Hosts, sau phương thức Run.
Nhưng kịch bản phổ biến nhất là bạn có thể cần quyền truy cập vào máy chủ trước phương thức app.Run, có hai cách để có quyền truy cập vào trình giám sát máy chủ.
Chúng ta đã thấy cách định cấu hình tất cả các máy chủ của ứng dụng theo đối số thứ hai của app.Run hoặc app.Configurehost. Có một cách khác phù hợp hơn cho các tình huống đơn giản và đó là sử dụng app.Newhost để tạo máy chủ mới và sử dụng một trong các phương thức  Serve hoặc Listen để khởi động ứng dụng thông qua iris # Raw Runner.
Lưu ý rằng cách này cần nhập thêm gói net / http.
Ví dụ:

h := app.NewHost(&http.Server{Addr:":8080"})
h.RegisterOnShutdown(func(){
    println("server terminated")
})

app.Run(iris.Raw(h.ListenAndServe))

 


Nhiều máy chủ

Bạn có thể phục vụ ứng dụng web Iris của mình bằng nhiều máy chủ, iris.Router tương thích với chức năng net / http / Handler, do đó bạn có thể hiểu nó có thể được sử dụng để điều chỉnh tại bất kỳ máy chủ net / http nào, tuy nhiên ở đó là một cách dễ dàng hơn, bằng cách sử dụng app.NewHost sao chép tất cả các cấu hình máy chủ lưu trữ và nó đóng tất cả các máy chủ được đính kèm với ứng dụng web trên app.Shutdown.

app := iris.New()
app.Get("/", indexHandler)

// run in different goroutine in order to not block the main "goroutine".
go app.Run(iris.Addr(":8080"))
// start a second server which is listening on tcp 0.0.0.0:9090,
// without "go" keyword because we want to block at the last server-run.
app.NewHost(&http.Server{Addr:":9090"}).ListenAndServe()

 


Shutdown

Let's continue by learning how to catch CONTROL+C/COMMAND+C or unix kill command and shutdown the server gracefully.

Chúng ta hãy tiếp tục bằng cách học cách tắt máy chủ bằng CONTROL+C/COMMAND+C hoặc unix kill.

Tắt máy chủ bằng cách  CONTROL+C/COMMAND+C hoặc khi lệnh hủy được gửi là ENABLED BY-DEFAULT.

Để quản lý thủ công những việc cần làm khi ứng dụng bị gián đoạn, chúng ta phải vô hiệu hóa hành vi mặc định bằng tùy chọn WithoutInterruptHandler và đăng ký trình xử lý ngắt mới (trên toàn cầu, trên tất cả các máy chủ có thể).


Ví dụ: 

package main

import (
    "context"
    "time"

    "github.com/kataras/iris/v12"
)


func main() {
    app := iris.New()

    iris.RegisterOnInterrupt(func() {
        timeout := 5 * time.Second
        ctx, cancel := context.WithTimeout(context.Background(), timeout)
        defer cancel()
        // close all hosts
        app.Shutdown(ctx)
    })

    app.Get("/", func(ctx iris.Context) {
        ctx.HTML(" <h1>hi, I just exist in order to see if the server is closed</h1>")
    })

    app.Run(iris.Addr(":8080"), iris.WithoutInterruptHandler)
}

 


Automatic Public Domain với TLS

Sẽ không tuyệt vời hơn khi kiểm tra máy chủ ứng dụng web của bạn trong một "real-world environment" (môi trường thế giới thực) như public, remote, address thay vì localhost?

Có rất nhiều công cụ của bên thứ ba cung cấp một tính năng như vậy, nhưng theo tôi ngrok là công cụ tốt nhất trong số đó. Nó phổ biến và được thử nghiệm trong nhiều năm, như Iris.

Iris cung cấp tích hợp ngrok. Tính năng này đơn giản nhưng rất mạnh mẽ. Nó thực sự hữu ích khi bạn muốn nhanh chóng thể hiện tiến trình phát triển của mình cho các đồng nghiệp hoặc trưởng dự án tại một hội nghị từ xa.

Thực hiện theo các bước bên dưới để tạm thời chuyển đổi máy chủ local web Iris của bạn sang máy chủ public.

  1. Tải ngrok và thêm nó vào biến môi trường của bạn $PATH
  2. Cấu hình WithTunneling trong app.Run
  3. Bạn đã sẵn sàng đến GO

 

  • ctx.Application().ConfigurationReadOnly().GetVHost() trả về giá trị miền public. Hiếm khi hữu ích nhưng nó có cho bạn. Hầu hết các lần bạn sử dụng đường dẫn url tương đối thay vì tuyệt đối

  • Không vấn đề gì nếu ngrok đã chạy hay chưa, Iris framework đủ thông minh để sử dụng web API để tạo một tunnel.

 Cấu hình Tunneling đầy đủ

app.Run(iris.Addr(":8080"), iris.WithConfiguration(
    iris.Configuration{
        Tunneling: iris.TunnelingConfiguration{
            AuthToken:    "my-ngrok-auth-client-token",
            Bin:          "/bin/path/for/ngrok",
            Region:       "eu",
            WebInterface: "127.0.0.1:4040",
            Tunnels: []iris.Tunnel{
                {
                    Name: "MyApp",
                    Addr: ":8080",
                },
            },
        },
}))

 

Phần tiếp theo chúng ta tìm hiểu về Configuration (cấu hình).