k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)

时间:2022-04-03 06:35:09

定时任务迁移kubernetes

服务迁移步骤

k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)

1.安装好java

2.安装好maven

  • 项目打包
    mvn package
  • 测试传参运行
    java -cp cronjob-demo-1.0-SNAPSHOT.jar com.mooc.demo.cronjob。Main
  • 编辑Dockfile
    FROM 172.17.166.172/kubenetes/openjdk:8-jre-alpine
    
    COPY target/cronjob-demo-1.0-SNAPSHOT.jar /cronjob-demo.jar
    
    ENTRYPOINT ["java", "-cp", "/cronjob-demo.jar", "com.mooc.demo.cronjob.Main" ]
  • 打包并运行测试镜像
    docker build -t cronjob-demo:v1 .
    docker run -it cronjob-demo:v1
  • 修改镜像tag并上传
    docker tag cronjob-demo:v1 172.17.166.17/kuberneres/cronjob-demo:v1
    
    docker push 172.17.166.17/kuberneres/cronjob-demo:v1
  • 制作k8s部署文件
    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
    name: cronjob-demo
    spec:
    schedule: "*/1 * * * *" #分时日月周
    successfulJobsHistoryLimit: 3 #成功任务历史保存个数
    suspend: false #是否停止 如果是true cronjob并不会调度起来
    concurrencyPolicy: Forbid #并行策略
    failedJobsHistoryLimit: 1 #失败保存个数
    jobTemplate:
    spec:
    template:
    metadata:
    labels:
    app: cronjob-demo
    spec:
    restartPolicy: Never #重启策略
    containers:
    - name: cronjob-demo
    image: 172.17.166.172/kubenetes/cronjob:v1
  • 查看任务
    kubectl apply -f conjob-demo.yaml
    kubectl get cronjob

【不熟悉SpringBoot的筒子看过来】SpringBoot快速入门

简介

SpringBoot使你可以非常容易的创建一个独立的、生产级的、基于spring的应用。

它大量简化了使用spring带来的繁琐的配置,大部分基于SpringBoot的应用只需要一点点的配置。

特征

  • 独立的spring应用(内置tomcat、jetty,无需部署war包)
  • 提供了丰富的"starter"依赖,简化应用构建配置
  • 自动配置spring和第三方依赖库
  • 没有代码生成,没有xml配置
  • 提供准生产功能,如指标,健康检查和外部配置

Quick Start

生成项目

访问官网:https://start.spring.io/

选择构建工具,如:Maven Project、Java、Spring Boot 版本 2.1.4 以及一些基本信息,如下图:

k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)

最终会下载到一个demo.zip,解压后主要目录结构如下

├── demo
│ ├── pom.xml
│ └── src
│ └── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── demo
│ │ └── DemoApplication.java
│ └── resources
│ └── application.properties

在demo基础上做一个web服务

改造后的pom
k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
</properties>
服务配置 - application.properties
# 服务名
server.name=springboot-web-demo
# web服务监听端口
server.port=8080
增加controller代码

com.example.demo.DemoController.java

package com.example.demo;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
public class DemoController { @RequestMapping("/hello")
public String sayHello() {
return "Hello SpringBoot";
} }
运行&测试

经过以上步骤,一个基于springboot的web服务就搭建好了。

运行方式如下:

  • 在IDE中:

    直接以DemoApplication做为启动类。
  • 在命令行下:
# 构建fatjar(构建结果在target目录下)
$ cd demo
$ mvn clean package # 运行jar包
$ java -jar target/demo-0.0.1-SNAPSHOT.jar

测试:

打开浏览器访问: http://localhost:8080/hello 看看效果吧

springboot的web服务迁移kubernetes

  • 打包
    mvn package
  • Dockerfile编写
    FROM 172.17.166.172/kubenetes/openjdk:8-jre-alpine
    
    COPY target/springboot-web-demo-1.0-SNAPSHOT.jar /web-demo.jar
    
    ENTRYPOINT ["java" , "-jar" , "/web-demo.jar"]
  • build镜像 测试并上传镜像
    jar -tf springboot-web-demo-1.0-SNAPSHOT.jar #查看jar包中包含的内容

    java -jar springboot-web-demo-1.0-SNAPSHOT.jar #测试包运行是否正常
    docker build -t springboot-web-demo:v1 . 

    docker run -it springboot-web-demo:v1

    docker tag springboot-web-demo:v1 172.17.166.217/kubernetes/springboot-web-demo:v1

    docker push springboot-web-demo:v1 172.17.166.217/kubernetes/springboot-web-demo:v1
  • 编辑k8s部署文件并运行
    k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)
    #deploy
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: web-demo
    spec:
    selector:
    matchLabels:
    app: springboot-web-demo
    replicas: 2
    template:
    metadata:
    labels:
    app: springboot-web-demo
    spec:
    containers:
    - name: springboot-web-demo
    image: 172.17.166.217/kubenetes/web:v1
    ports:
    - containerPort: 8080
    ---
    #service
    apiVersion: v1
    kind: Service
    metadata:
    name: springboot-web-demo
    spec:
    ports:
    - port: 80
    protocol: TCP
    targetPort: 8080
    selector:
    app: springboot-web-demo
    type: ClusterIP ---
    #ingress
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    name: springboot-web-demo
    spec:
    rules:
    - host: www.cssp.com
    http:
    paths:
    - pathType: Prefix
    path: /
    backend:
    service:
    name: springboot-web-demo
    port:
    number: 80

    spring-web-demo.yaml

    kubectl apply -f spring-web-demo.yaml
    
    kubectl get deploy spring-web-demo
    
    kubectl get pod -l app.kubernetes.io/name=spring-web-demo

Dubbo快速入门

简介

Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

Dubbo源自阿里巴巴,2018年初贡献给了apache基金会。已经经历两年多的孵化。

据悉,2.7.x会作为Dubbo在Apache社区的毕业版本,Dubbo将有机会成为继RocketMQ后,来自阿里巴巴的又一个Apache*项目(TLP)。

架构

dubbo主要有三种角色:

  • 服务的提供者

    启动后会把服务的信息写入注册中心(服务的ip地址,端口,有哪些接口等)
  • 服务消费者

    访问注册中心找到服务提供者的信息,并跟服务提供者建立连接。
  • 注册中心

    主要作用是存储服务的信息,并对服务的变化做通知。

k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)

Quick Start

最常见的使用dubbo的方式是基于spring框架。下面的内容也是基于spring框架的配置去演示如何开发一个基于dubbo的应用。

首先我们创建一个根目录叫:dubbo-demo:

$ mkdir dubbo-demo
$ cd dubbo-demo

然后在根目录下创建三个子目录:

  • dubbo-demo-api: 服务的api定义
  • dubbo-demo-provider: 服务提供者
  • dubbo-demo-consumer: 服务消费者

1. 注册中心 - zookeeper

dubbo常用的注册中心是zookeeper,首先用docker启动一个zookeeper服务,暴露出2181端口。

docker run -idt -p 2181:2181 zookeeper:3.5

2. dubbo-demo-api - 服务接口定义

定义服务接口(DemoService.java)

package org.apache.dubbo.demo;

public interface DemoService {
String sayHello(String name);
}

此时工程的结构应该类似这样:

├── dubbo-demo-api
│ ├── pom.xml
│ └── src
│ └── main
│ └── java
│ └── org
│ └── apache
│ └── dubbo
│ └── demo
│ └── DemoService.java

3. dubbo-demo-provider - 服务提供者

服务实现类(DemoServiceImpl.java)
package org.apache.dubbo.demo.provider;
import org.apache.dubbo.demo.DemoService; public class DemoServiceImpl implements DemoService {
public String sayHello(String name) {
return "Hello " + name;
}
}
服务启动类(Provider.java)
package org.apache.dubbo.demo.provider;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Provider {

    public static void main(String[] args) throws Exception {
System.setProperty("java.net.preferIPv4Stack", "true");
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-provider.xml"});
context.start();
System.out.println("Provider started.");
System.in.read(); // press any key to exit
}
}
通过spring配置暴露服务(provider.xml)
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 服务提供者的应用名 -->
<dubbo:application name="demo-provider"/>
<!-- 把服务注册到zookeeper -->
<dubbo:registry address="zookeeper://${zookeeper_ip_addr}:2181"/>
<!-- 使用dubbo协议暴露服务端口20880 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- 服务的实现类 -->
<bean id="demoService" class="org.apache.dubbo.demo.provider.DemoServiceImpl"/>
<!-- 声明要暴露的服务接口 -->
<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService"/>
</beans>
配置日志(log4j.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<param name="encoding" value="UTF-8"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] {%p} %c %L - %m%n" />
</layout>
</appender>
<root>
<level value="warn" />
<appender-ref ref="stdout" />
</root>
</log4j:configuration>
最终项目结构如下
├── dubbo-demo-provider
│ ├── pom.xml
│ └── src
│ └── main
│ ├── java
│ │ └── org
│ │ └── apache
│ │ └── dubbo
│ │ └── demo
│ │ └── provider
│ │ ├── DemoServiceImpl.java
│ │ └── Provider.java
│ └── resources
│ ├── META-INF
│ │ └── spring
│ │ └── dubbo-demo-provider.xml
│ └── log4j.xml

4. dubbo-demo-consumer - 服务消费者

用下面的spring配置引用一个远程的dubbo服务(consumer.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 消费者应用名 -->
<dubbo:application name="demo-consumer"/>
<!-- 用zookeeper发现服务 -->
<dubbo:registry address="zookeeper://${zookeeper_ip_addr}:2181"/>
<!-- 生成远程服务的代理, 之后demoService就可以像使用本地接口一样使用了 -->
<dubbo:reference id="demoService" check="false" interface="org.apache.dubbo.demo.DemoService"/>
</beans>
消费者启动类(Consumer.java)
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.apache.dubbo.demo.DemoService; public class Consumer {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"META-INF/spring/dubbo-demo-consumer.xml"});
context.start();
// Obtaining a remote service proxy
DemoService demoService = (DemoService)context.getBean("demoService");
// Executing remote methods
String hello = demoService.sayHello("world");
// Display the call result
System.out.println(hello);
}
}
配置好日志后(同provider),项目结构如下:
├── dubbo-demo-consumer
│ ├── pom.xml
│ └── src
│ └── main
│ ├── java
│ │ └── org
│ │ └── apache
│ │ └── dubbo
│ │ └── demo
│ │ └── consumer
│ │ └── Consumer.java
│ └── resources
│ ├── META-INF
│ │ └── spring
│ │ └── dubbo-demo-consumer.xml
│ └── log4j.xml

5. 完整示例

  • provider
$ git clone https://github.com/apache/incubator-dubbo.git
$ cd incubator-dubbo
在模块dubbo-demo-provider下运行org.apache.dubbo.demo.provider.Provider
如果用的IDE是Intellij Idea,需要添加参数:-Djava.net.preferIPv4Stack=true
  • consumer
$ git clone https://github.com/apache/incubator-dubbo.git
$ cd incubator-dubbo
如果用的IDE是Intellij Idea,需要添加参数:-Djava.net.preferIPv4Stack=true

传统dubbo服务迁移kubernetes

  • 打包

    mvn install #进入dubbo api目录安装dubbo api
    
    mvn package #打包
    
    tar -tf dubbo-demo-1.0-SNPASHOT-assembly.tar.gz 查看包中包含具体资源
  • 测试
    /bin/start.sh 启动服务
    
    查看接口是否开放 进程是否存在
    telnet ip dubbo端口连接 ls 查看服务 ls com.mooc.demo.api.DemoService 查看有哪些服务接口 invoke com.mooc.demo.api.DemoService.sayHello("Dick")调用接口 /bin/stop.sh 测试停止服务
  • 制作dockerfile并测试
    FROM hub.mooc.com/kubernetes/openjdk:8-jre-alpine
    
    COPY target/ROOT /ROOT
    
    ENTRYPOINT ["sh", "/ROOT/bin/start.sh"]
  • dubbo服务发现

k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)

1.provider向zookeeper注册,zookeeper返回给consumer容器ip

2.如整体架构都在k8s中则无问题,如consumer在集群之外。

3.provider可将真实宿主机ip通过文件挂载方式configmap挂载到provider evn中。注册时使用真实ip。缺点(性能消耗不好,使用不方便)

4.provider可使用宿主机网络,hostnetwork。直接与宿主机共用网络。缺点端口会增多混乱所以要规划好端口使用问题。

5.优雅退出dubbo优雅退出是系统向程序发送一个SIGTERM信号kill 15终止信号,出发代码run中方法去执行下线流程。kubelet关闭容器默认也是发送SIGTERM kill 15信号与微服务契合。有可能遇到Pod卡死,处理不了优雅退出的命令或者操作、优雅退出的逻辑有BUG,陷入死循环、代码问题,导致执行的命令没有效果。所以可以在prostop中加入脚本向注册中心通知下线操作。

  • k8s部署文件
    k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: dubb-demo
    spec:
    selector:
    matchLabels:
    app: dubb-demo
    replicas: 1
    template:
    metadata:
    labels:
    app: dubb-demo
    spec:
    hostNetwork: true
    affinity:
    podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
    matchExpressions:
    - key: app
    operator: In
    values:
    - dubb-demo
    topologyKey: "kubernetes.io/hostname"
    containers:
    - name: dubb-demo
    image: hub.mooc.com/kubernetes/dubbo:v1
    ports:
    - containerPort: 20881
    env:
    - name: DUBBO_PORT
    value: "20881" #在启动文件中替换端口

    dubbo.yaml

传统web服务迁移kubernetes

  • 打包测试
    mvn package
  • 构建dockerfile 
    k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)
    FROM 172.17.166.217/kubenetes/tomcat:8.0.51-alpine
    
    COPY ROOT /usr/local/tomcat/webapps/ROOT
    
    COPY dockerfiles/start.sh /usr/local/tomcat/bin/start.sh
    
    ENTRYPOINT ["sh" , "/usr/local/tomcat/bin/start.sh"]

    tomcat.yaml

  • 镜像测试后将镜像上传库并制作k8s文件
    k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: web-demo
    spec:
    selector:
    matchLabels:
    app: web-demo
    replicas: 4
    template:
    metadata:
    labels:
    app: web-demo
    spec:
    containers:
    - name: web-demo
    image: hub.mooc.com/kubernetes/web:v1
    ports:
    - containerPort: 8080

    tomcat.yaml

    ###注默认tomcat启动是后台运行,容器收不到存活进程会自动退出,要在启动文件中编辑一个循环指令。类似于

    #!/bin/bash
    
    sh /usr/local/tomcat/bin/startup.sh
    
    tail -f /usr/local/tomcat/logs/catalina.out

k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)的更多相关文章

  1. k8s入坑之路(16)kubernetes中CICD&sol;基于宿主机jenkins

    cicd的结合组件 需要代码仓库如gitlab.github.包构建工具Maven等,持续集成工具如jenkins,github/cicd.结合自己脚本实现重复式任务自动化. 传统服务发布流程: 提交 ...

  2. k8s入坑之路(12)ingress-nginx安装配置四层代理

    ingress官方文档地址:http://docs.kubernetes.org.cn/  https://feisky.gitbooks.io/kubernetes/content/plugins/ ...

  3. k8s入坑之路(10)kubernetes coredns详解

    概述 作为服务发现机制的基本功能,在集群内需要能够通过服务名对服务进行访问,那么就需要一个集群范围内的DNS服务来完成从服务名到ClusterIP的解析. DNS服务在kubernetes中经历了三个 ...

  4. k8s入坑之路(13)kubernetes重要资源(namespace隔离 resources资源管理 label)

    Namespace --- 集群的共享与隔离 语言中namespace概念 namespace核心作用隔离 以上是隔离的代码.namespace隔离的是: 1.资源对象的隔离:Service.Depl ...

  5. k8s入坑之路(11)kubernetes服务发现

    kubernetes访问场景 1.集群内部访问 2.集群内部访问外部 3.集群外部访问内部 1.集群内部访问 1.pod之间直接ip通讯(利用calico通过路由表经过三层将ip流量转发)由于容器之间 ...

  6. k8s入坑之路(9)k8s网络插件详解

    Flannel: 最成熟.最简单的选择 Calico: 性能好.灵活性最强,目前的企业级主流 Canal: 将Flannel提供的网络层与Calico的网络策略功能集成在一起. Weave: 独有的功 ...

  7. k8s入坑之路(7)kubernetes设计精髓List&sol;Watch机制和Informer模块详解

    1.list-watch是什么 List-watch 是 K8S 统一的异步消息处理机制,保证了消息的实时性,可靠性,顺序性,性能等等,为声明式风格的API 奠定了良好的基础,它是优雅的通信方式,是 ...

  8. k8s入坑之路(4)kubenetes安装

    三种安装方法: 1.kubeadm 2.kubespray 3.二进制安装 kubespray安装kubernetes集群 优点: 1.kuberspray对比kubeadm更加简洁内部集成了kube ...

  9. k8s入坑之路(15)kubernetes共享存储与StatefulSet有状态

    共享存储 docker默认是无状态,当有状态服务时需要用到共享存储 为什么需要共享存储: 1.最常见有状态服务,本地存储有些程序会把文件保存在服务器目录中,如果容器重新启停则会丢失. 2.如果使用vo ...

随机推荐

  1. 【blade04】用面向对象的方法写javascript坦克大战

    前言 javascript与程序的语言比如C#或者java不一样,他并没有“类”的概念,虽然最新的ECMAScript提出了Class的概念,我们却没有怎么用 就单以C#与Java来说,要到真正理解面 ...

  2. Asp&period;net Mvc4 使用Cas单点登录

    因项目需要,使用了耶鲁大学的Cas单点登录方案,在java中使用一直正常,但是在.Net中碰到了循环重定向的问题,反复测试后,总算解决了,最终的配置如下: <?xml version=&quot ...

  3. java之多线程(Thread)

    package DEMO; //主线程 public class Example12_2 { public static void main(String [] args ) { Thread myd ...

  4. windows下django1&period;7 &plus;python3&period;4&period;2搭建记录2

    1.自定义页面写一个显示当前时间的页面views.py文件加一个使用模板的模块,整体内容为: #coding=utf-8 from django.shortcuts import render fro ...

  5. Android WebView 开发详解&lpar;二&rpar;

    转载请注明出处  http://blog.csdn.net/typename/article/details/39495409 powered by miechal zhao   概览: Androi ...

  6. 线性表之顺序存储结构(C语言动态数组实现)

    线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链 ...

  7. POJ1840 hash

    POJ1840 问题重述: 给定系数a1,a2, ..,a5,求满足a1 * x1 ^ 3 + a2 * x2 ^ 3 +... + a5 * x5 ^ 3 = 0的 xi 的组数.其中ai, xi都 ...

  8. linux下tomcat作为daemon进程运行

    在linux下如果想让tomcat在开机时自启动,可以将启动代码写到/etc/rc.local里面.但是,这样的话,tomcat将以root权限运行,这是不安全的.因此,要想办法让tomcat以非特权 ...

  9. MySQL 最左前缀&lpar;Leftmost Prefix&rpar; &amp&semi; 组合索引&lpar;复合索引,多列索引&rpar;

    资料来源于网络,仅供参考学习. CREATE TABLE test(a INT,b INT,c INT,KEY idx(a,b,c)); 优: SELECT * FROM test WHERE a=1 ...

  10. multiThread &lpar;一)

    并发系列(1)之 Thread 详解   阅读目录 一.线程概述 二.线程状态 三.源码分析 1. native注册 2. 构造方法和成员变量 3. start 方法 4. exit 方法 5. 弃用 ...