Commit b60bb6c9 authored by Nane Kratzke's avatar Nane Kratzke
Browse files

Finalize Lab

parent 91eb6981
......@@ -199,16 +199,31 @@ Hierzu sind im Verzeichnis `deploy` entsprechende Deployments und Services sowie
- `deploy/rest-dep.yaml` und `deploy/rest-svc.yaml` deployed insgesamt 5 Pods mit REST-API (in einem Cluster von fünf Knoten) und fasst diese zu einem REST-Service zusammen.
- `deploy/monitor-dep.yaml` deployed einen Pod mit der `compare.py`-Funktionalität, der den REST- und gRPC-Service analog zu Übung 3 in Kubernetes abfragt und die Latenzen ermittelt und loggt.
Durch dieses Setting ist sichergestellt, dass der Monitor Pod sowohl Pods auf seinem eigenen Node als auch auf anderen Nodes abfragt, um sowohl Intra- als auch Inter-Node Calls abzudecken.
Stoßen Sie also bitte jetzt die Deployment Pipeline an und verfolgen Sie in Lens wie die REST- und gRPC-Pods deployed werden. Wenn dies erfolgt ist triggern Sie dann bitte in der Gitlab Pipeline den manuellen `monitor`-Job der `deploy`-Stage.
Verfolgen Sie in Lens das Pod Log des `monitor`-Pods.
Verfolgen Sie in Lens das Log (`Pods -> Monitor Pod (auswählen) -> Log`) des `monitor`-Pods. Sie sollten dann ein Log wie dieses hier in etwa sehen:
```
gRPC: 00.66ms REST: 04.70ms
gRPC: 00.63ms REST: 04.59ms
gRPC: 00.61ms REST: 04.41ms
gRPC: 00.60ms REST: 04.39ms
gRPC: 00.59ms REST: 04.40ms
gRPC: 00.60ms REST: 04.42ms
gRPC: 00.61ms REST: 04.47ms
[...]
```
Vermutlich sind die Latenzen anders als auf ihrem lokalen System (je nachdem was für ein System Sie haben). Allerdings sollten auch im Cluster die gRPC-Latenzen gegenüber den REST-Latenzen deutlich niedriger sein. Vermutlich ist dies sogar deutlich ausgeprägter.
## Verständnis- und Transferfragen
- Welche Art der API-Entwicklung erscheint Ihnen "zugänglicher" (REST, gRPC)?
- Wie schätzen Sie den Grad der Kopplung bei REST und gRPC ein und warum?
- Erklären Sie die gemessenen Performance-Unterschiede zwischen Übung 03 und Übung 04. Benennen Sie ein paar Komponenten, die dafür verantwortlich sein könnten.
- Wie schätzen Sie vor dem Hintergrund der Zahlen die Leistungsfähigkeit des Ihnen zur Verfügung gestellten Clusters im Vergleich zu Ihrem eigenen System ein?
Zur Beantwortung der folgenden Fragen, füllen Sie bitte die folgende Tabelle aus.
......
import requests, time, os
from statistics import median
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
grpc_svc = os.environ.get("GRPC_SVC", "localhost")
grpc_port = os.environ.get("GRPC_PORT", "5555")
rest_svc = os.environ.get("REST_SVC", "localhost")
rest_port = os.environ.get("REST_PORT", "5000")
channel = grpc.insecure_channel(f"{ grpc_svc }:{ grpc_port }")
stub = helloworld_pb2_grpc.GreeterStub(channel)
grpc_s = []
rest_s = []
while True:
for i in range(0, 100):
start = time.time()
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
grpc_s.append(time.time() - start)
start = time.time()
x = requests.get(f"http://{ rest_svc }:{ rest_port }/hello/you")
rest_s.append(time.time() - start)
print(f"gRPC: { median(grpc_s) * 1000 :05.2f}ms REST: { median(rest_s) * 1000 :05.2f}ms")
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: helloworld.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='helloworld.proto',
package='',
syntax='proto3',
serialized_options=None,
create_key=_descriptor._internal_create_key,
serialized_pb=b'\n\x10helloworld.proto\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t23\n\x07Greeter\x12(\n\x08SayHello\x12\r.HelloRequest\x1a\x0b.HelloReply\"\x00\x62\x06proto3'
)
_HELLOREQUEST = _descriptor.Descriptor(
name='HelloRequest',
full_name='HelloRequest',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='name', full_name='HelloRequest.name', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=20,
serialized_end=48,
)
_HELLOREPLY = _descriptor.Descriptor(
name='HelloReply',
full_name='HelloReply',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='message', full_name='HelloReply.message', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=50,
serialized_end=79,
)
DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST
DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), {
'DESCRIPTOR' : _HELLOREQUEST,
'__module__' : 'helloworld_pb2'
# @@protoc_insertion_point(class_scope:HelloRequest)
})
_sym_db.RegisterMessage(HelloRequest)
HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), {
'DESCRIPTOR' : _HELLOREPLY,
'__module__' : 'helloworld_pb2'
# @@protoc_insertion_point(class_scope:HelloReply)
})
_sym_db.RegisterMessage(HelloReply)
_GREETER = _descriptor.ServiceDescriptor(
name='Greeter',
full_name='Greeter',
file=DESCRIPTOR,
index=0,
serialized_options=None,
create_key=_descriptor._internal_create_key,
serialized_start=81,
serialized_end=132,
methods=[
_descriptor.MethodDescriptor(
name='SayHello',
full_name='Greeter.SayHello',
index=0,
containing_service=None,
input_type=_HELLOREQUEST,
output_type=_HELLOREPLY,
serialized_options=None,
create_key=_descriptor._internal_create_key,
),
])
_sym_db.RegisterServiceDescriptor(_GREETER)
DESCRIPTOR.services_by_name['Greeter'] = _GREETER
# @@protoc_insertion_point(module_scope)
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
import helloworld_pb2 as helloworld__pb2
class GreeterStub(object):
"""The greeting service definition.
"""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.SayHello = channel.unary_unary(
'/Greeter/SayHello',
request_serializer=helloworld__pb2.HelloRequest.SerializeToString,
response_deserializer=helloworld__pb2.HelloReply.FromString,
)
class GreeterServicer(object):
"""The greeting service definition.
"""
def SayHello(self, request, context):
"""Sends a greeting
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_GreeterServicer_to_server(servicer, server):
rpc_method_handlers = {
'SayHello': grpc.unary_unary_rpc_method_handler(
servicer.SayHello,
request_deserializer=helloworld__pb2.HelloRequest.FromString,
response_serializer=helloworld__pb2.HelloReply.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'Greeter', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class Greeter(object):
"""The greeting service definition.
"""
@staticmethod
def SayHello(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/Greeter/SayHello',
helloworld__pb2.HelloRequest.SerializeToString,
helloworld__pb2.HelloReply.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
import flask
app = flask.Flask(__name__)
@app.route('/', methods=['GET'])
def home():
return f"Hello!"
@app.route('/hello/<name>', methods=['GET'])
def hello(name):
return f"Hello, { name.strip() }!"
app.run(host="0.0.0.0")
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment