docker+k8s+istio项目实例
0.本博客目标■■■■■■■■■■■■■■■■最近学习k8s+istio项目知识,本博客只是想把项目学习经验分享给大家,以便大家少走弯路。k8s,isito的知识点众多,内容体系庞杂,本博客只做简单验证,能够让你快速搭建起运行环境,并且快速搭建项目验证k8s及istio。1.运行环境■■■■■■■■■■■■■■■■Linux centos7.6Docker 18.09.0kubernetes 1.
0.本博客目标■■■■■■■■■■■■■■■■
最近学习k8s+istio项目知识,本博客只是想把项目学习经验分享给大家,以便大家少走弯路。
k8s,isito的知识点众多,内容体系庞杂,本博客只做简单验证,能够让你快速搭建起运行环境,并且快速搭建项目验证k8s及istio。
1.运行环境■■■■■■■■■■■■■■■■
Linux centos7.6
Docker 18.09.0
kubernetes 1.14.0-0
istio-1.4.10
运行的业务项目为Java项目,JDK1.8
2.环境安装■■■■■■■■■■■■■■■■
★2.0.更新yum源(3个节点都安装)■■■■■■
yum -y update
yum install -y conntrack ipvsadm ipset jq sysstat curl iptables libseccomp
★2.1.docker安装(3个几点都安装)■■■■■■
yum install -y docker-ce-18.09.0 docker-ce-cli-18.09.0 containerd.io
设置开机启动
sudo systemctl start docker && sudo systemctl enable docker
★2.2.kubernetes安装■■■■■■
我这里k8s集群安装1主2从安装。
●修改hosts文件■■■■
主节点:设置master的hostname,并且修改hosts文件
sudo hostnamectl set-hostname m
vi /etc/hosts
192.168.42.130 m
192.168.42.131 w1
192.168.42.132 w2
2个从节点:设置worker01/02的hostname,并且修改hosts文件
sudo hostnamectl set-hostname w1
sudo hostnamectl set-hostname w2
vi /etc/hosts
192.168.42.130 m
192.168.42.131 w1
192.168.42.132 w2
设置完后,互相ping一下(ping m/ping w1/ping w2),确认设置没有问题。
●系统基础前提配置(3个节点都安装)■■■■
▲1.关闭防火墙■■
systemctl stop firewalld && systemctl disable firewalld
▲2.关闭selinux■■
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
▲3.关闭swap■■
swapoff -a
sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab
▲4.配置iptables的ACCEPT规则■■
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat && iptables -P FORWARD ACCEPT
▲5.设置系统参数■■
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
●安装 kubeadm,kubelet 和 kubectl(3个节点都安装)■■■■
▲1.配置yum源■■
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
▲2.安装kubeadm,kubelet 和 kubectl■■
yum -y install kubernetes-cni = 0.7.5
yum install -y kubeadm-1.14.0-0 kubelet-1.14.0-0 kubectl-1.14.0-0
yum -y remove kubelet
yum install -y kubelet-1.14.0-0
yum install -y kubeadm-1.14.0-0
▲3.docker和k8s设置同一个cgroup■■
docker
vi /etc/docker/daemon.json
exec-opts:["native.cgroupdriver-systemd"],
systemctl restart docker
kubelet
sed -i "s/cgroup-driver=systemd/cgroup-driver=cgroupfs/g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
systemctl enable kubelet && systemctl start kubelet
安装k8s时需要使用一些国外镜像。由于这些镜像不能直接访问,所以需要特殊处理一下。
▲4.下载国外镜像方法■■
需要先注册一个dockerhub的账号,然后通过dockerhub中转一下获取国外的镜像。dockerhub国内是可以访问到的,不过速度有点慢,需要忍耐一下。dockerhub地址:https://docs.docker.com/
随便点开一个课程,进入该课程,可以看到一个终端,如图所示:
之后在该终端执行以下操作:
# 登录dockerhub,我的用户名是ryuu
docker login
# 由于kacacoda是国外网站,所以可以直接在它的终端上拉取gcr镜像
docker pull docker.io/istio/kubectl:1.4.10
# 给镜像改名,一定要是: 你的dockerhub用户名/镜像名:版本,否则无法推送到自己的镜像仓库
docker tag docker.io/istio/kubectl:1.4.10 ryuu/istio-kubectl:1.4.10
# 推送到自己的dockerhub镜像仓库
docker push ryuu/istio-kubectl:1.4.10
这样就把国外的镜像拉取到了dockerhub镜像仓库中,然后在从dockerhub中拉取到本地,然后再打tag为原来的镜像名称,就完成了国外镜像的获取。
※需要下载的镜像
k8s.gcr.io/kube-apiserver:v1.14.0
k8s.gcr.io/kube-controller-manager:v1.14.0
k8s.gcr.io/kube-scheduler:v1.14.0
k8s.gcr.io/kube-proxy:v1.14.0
k8s.gcr.io/pause:3.1
k8s.gcr.io/etcd:3.3.10
k8s.gcr.io/coredns:1.3.1
▲5.初始化主节点(在master上安装 ip:192.168.42.130)■■
kubeadm init --kubernetes-version=1.14.0 --apiserver-advertise-address=192.168.42.130 --pod-network-cidr=10.244.0.0/16
安装完成后获取日志中以下部分内容
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubeadm join 192.168.42.130:6443 --token z3qetd.qzp04u03bvq9eeos \
--discovery-token-ca-cert-hash sha256:0e7980b860a4ef29281469966f50b60dd8dbb608c2fdb3a971df81968aafb5ee
上面3行的命令需要在主节点上执行一遍。后面2行的内容在2个从节点上执行,用于将从节点加入集群。
▲6.安装网络插件calico(在主节点操作)■■
需要事先下载以下镜像
calico/pod2daemon-flexvol:v3.9.1
calico/kube-controllers:v3.9.1
calico/cni:v3.9.1
kubectl apply -f https://docs.projectcalico.org/v3.9/manifests/calico.yaml
确认calico安装成功(可以看到calico的pod被启动起来即表示安装成功)
kubectl get pods --all-namespaces -w
▲7.将2个从节点加入集群■■
kubeadm join 192.168.42.130:6443 --token z3qetd.qzp04u03bvq9eeos \
--discovery-token-ca-cert-hash sha256:0e7980b860a4ef29281469966f50b60dd8dbb608c2fdb3a971df81968aafb5ee
确认从节点加入成功,在主节点上操作
kubectl get nodes
看到2个从节点即表示成功。
▲8.安装Ingress■■
需要事先下载镜像
quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1
给node打标签(用于指定ingress安装的node)
kubectl label nodes w1 name=ingress
安装ingress
kubectl apply -f mandatory.yaml
对应的脚本文件mandatory.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: udp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: nginx-ingress-clusterrole
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- "extensions"
- "networking.k8s.io"
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
- "networking.k8s.io"
resources:
- ingresses/status
verbs:
- update
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: nginx-ingress-role
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
resourceNames:
# Defaults to "<election-id>-<ingress-class>"
# Here: "<ingress-controller-leader>-<nginx>"
# This has to be adapted if you change either parameter
# when launching the nginx-ingress-controller.
- "ingress-controller-leader-nginx"
verbs:
- get
- update
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- apiGroups:
- ""
resources:
- endpoints
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: nginx-ingress-role-nisa-binding
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nginx-ingress-role
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nginx-ingress-clusterrole-nisa-binding
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: nginx-ingress-clusterrole
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
spec:
# wait up to five minutes for the drain of connections
terminationGracePeriodSeconds: 300
serviceAccountName: nginx-ingress-serviceaccount
hostNetwork: true
nodeSelector:
name: ingress
kubernetes.io/os: linux
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
securityContext:
allowPrivilegeEscalation: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
# www-data -> 33
runAsUser: 33
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
---
至此k8s集群搭建完成。
★2.3.istio安装■■■■■■
●1.下载压缩包,并解压(istio-1.4.10-linux.tar.gz)■■■■
●2.解压压缩包后配置环境变量■■■■
vi /etc/profile
export ISTIO_HOME=/opt/istio/istio-1.4.10
export PATH=$PATH:$ISTIO_HOME/bin
source /etc/profile
●3.安装isito■■■■
需要事先下载以下镜像
docker.io/istio/kubectl:1.4.10
docker.io/istio/galley:1.4.10
grafana/grafana:6.4.3
quay.io/kiali/kiali:v1.15
docker.io/istio/mixer:1.4.10
docker.io/istio/proxyv2:1.4.10
docker.io/istio/pilot:1.4.10
docker.io/prom/prometheus:v2.12.0
docker.io/istio/citadel:1.4.10
docker.io/istio/sidecar_injector:1.4.10
docker.io/jaegertracing/all-in-one:1.14
cd /opt/istio/istio-1.4.10/install/kubernetes
kubectl apply -f istio-demo.yaml
查看istio对应的pod正常启动,确认istio安装正常
kubectl get pods -n istio-system
3.示例项目■■■■■■■■■■■■■■■■
示例羡慕整合了数据库(PostgreSQL)和分布式事务中间件(Seata)。本项目访问外部服务采用直接访问的方式,istio天然支持这种方式。外部访问项目时,采用ingress gateway方式。
项目分为3个服务(istio-client,istio-service1,istio-service2)。其中istio-client分别调用istio-service1和istio-service2。
★3.1.istio-client■■■■■■
1.项目结构
●SeataConfig.java
package com.istioclient.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.seata.spring.annotation.GlobalTransactionScanner;
@Configuration
public class SeataConfig {
@Bean
public GlobalTransactionScanner globalTransactionScanner() {
return new GlobalTransactionScanner("istioClient-gts-seata", "istio_tx_group");
}
}
●TestController.java
package com.istioclient.controller;
import com.istioclient.service.TestService;
import com.istioclient.util.HttpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class TestController {
private Logger logger = LoggerFactory.getLogger(TestController.class);
@Autowired
TestService testService;
@Autowired
private HttpUtil httpUtil;
@Value("${istio.service1.url}")
private String istioService1Url;
@Value("${istio.service2.url}")
private String istioService2Url;
@RequestMapping("/getTest1")
public String getTest1(){
logger.info("#############getTest1");
String res = httpUtil.callAService(istioService1Url + "/test1/getTest1");
return res;
}
@RequestMapping("/getTest2")
public String getTest2(){
logger.info("#############getTest2");
String res = httpUtil.callAService(istioService2Url + "/test2/getTest2");
return res;
}
@RequestMapping("/seataTest")
public String seataTest(){
logger.info("#############seataTest");
return testService.seataTest();
}
}
●TestService.java
package com.istioclient.service;
import com.istioclient.util.HttpUtil;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class TestService {
@Autowired
private HttpUtil httpUtil;
@Value("${istio.service1.url}")
private String istioService1Url;
@Value("${istio.service2.url}")
private String istioService2Url;
@GlobalTransactional
public String seataTest(){
String test1 = httpUtil.callAService(istioService1Url + "/test1/insertTest1");
String test2 = httpUtil.callAService(istioService2Url + "/test2/insertTest4");
return test1 + "||" + test2;
}
}
●HttpUtil.java
package com.istioclient.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
@Component
public class HttpUtil {
@Autowired
private RestTemplate restTemplate;
public String callAService(String serviceUrl){
try {
//■■■组装headers 以下header用于istio服务网格追踪你的调用链,参数无需手动赋值
HttpHeaders headers = new HttpHeaders();
headers.add("x-request-id",null);
headers.add("x-b3-traceid",null);
headers.add("x-b3-spanid",null);
headers.add("x-b3-parentspanid",null);
headers.add("x-b3-sampled",null);
headers.add("x-b3-flags",null);
headers.add("x-ot-span-context",null);
headers.add("x-cloud-trace-context",null);
headers.add("traceparent",null);
headers.add("grpc-trace-bin",null);
//■■■组装请求参数
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("key","value");
HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(requestBody, headers);
//参数1:访问url
//参数2:返回值类型
//参数3...:访问url带的参数列表
// restTemplate.getForEntity(url,entity.class,Sting1,int2);
// restTemplate.getForObject(url,Object.class,int1,long2);
//参数1:访问url
//参数2:访问url带的参数
//参数3:返回的类型
// restTemplate.postForEntity(url,entity,entity.class);
return restTemplate.getForObject(serviceUrl, String.class,httpEntity);
} catch (RestClientException e) {
return e.getMessage();
}
}
}
●IstioCliApp.java
package com.istioclient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class IstioCliApp {
public static void main(String[] args) {
try {
ConfigurableApplicationContext ca = SpringApplication.run(IstioCliApp.class, args);
System.out.println(System.getenv("SERVICES_DOMAIN"));
System.out.println("■■■■■启动正常");
}catch(Exception e){
e.printStackTrace();
System.out.println("■■■■■启动异常");
}
}
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}
●application.properties
spring.profiles.active=istio
server.port=8080
###■■■■restTemplate连接池
#最大连接数
http.maxTotal=100
#并发数
http.defaultMaxPerRoute=20
#创建连接的最长时间
http.connectTimeout=1000
#从连接池中获取到连接的最长时间
http.connectionRequestTimeout=500
#数据传输的最长时间
http.socketTimeout=10000
#提交请求前测试连接是否可用
http.staleConnectionCheckEnabled=true
#可用空闲连接过期时间,重用空闲连接时会先检查是否空闲时间超过这个时间,如果超过,释放socket重新建立
http.validateAfterInactivity=3000000
●application-dev.properties
#istio-service1地址
istio.service1.url=http://localhost:8081
#istio-service2地址
istio.service2.url=http://localhost:8082
●application-istio-properties
#istio-service1地址
istio.service1.url=http://10.108.232.20:8081
#istio-service2地址
istio.service2.url=http://10.108.232.30:8082
●file.conf
transport {
# tcp udt unix-domain-socket
type = "TCP"
#NIO NATIVE
server = "NIO"
#enable heartbeat
heartbeat = true
# the client batch send request enable
enableClientBatchSendRequest = true
#thread factory for netty
threadFactory {
bossThreadPrefix = "NettyBoss"
workerThreadPrefix = "NettyServerNIOWorker"
serverExecutorThread-prefix = "NettyServerBizHandler"
shareBossWorker = false
clientSelectorThreadPrefix = "NettyClientSelector"
clientSelectorThreadSize = 1
clientWorkerThreadPrefix = "NettyClientWorkerThread"
# netty boss thread size,will not be used for UDT
bossThreadSize = 1
#auto default pin or 8
workerThreadSize = "default"
}
shutdown {
# when destroy server, wait seconds
wait = 3
}
serialization = "seata"
compressor = "none"
}
service {
#transaction service group mapping
vgroupMapping.istio_tx_group = "default"
#only support when registry.type=file, please don't set multiple addresses
#■■■■■■■■■■■■■ seata 地址设置 start ■■■■■■■■■■■■■
default.grouplist = "172.22.70.72:8091"
#■■■■■■■■■■■■■ seata 地址设置 end ■■■■■■■■■■■■■
#degrade, current not support
enableDegrade = false
#disable seata
disableGlobalTransaction = false
}
client {
rm {
asyncCommitBufferLimit = 10000
lock {
retryInterval = 10
retryTimes = 30
retryPolicyBranchRollbackOnConflict = true
}
reportRetryCount = 5
tableMetaCheckEnable = false
reportSuccessEnable = false
}
tm {
commitRetryCount = 5
rollbackRetryCount = 5
}
undo {
dataValidation = true
logSerialization = "jackson"
logTable = "undo_log"
}
log {
exceptionRate = 100
}
}
●log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<!-- ■■■■■ 要使这个配置生效,需要pom中排除掉spring-boot-starter-logging ■■■■■ -->
<!--全局参数-->
<Properties>
<!--
%d{yyyy-MM-dd HH:mm:ss.SSS} =>格式化时间 2020-01-21 14:03:53.858
%5p =>输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%t =>输出产生该日志事件的线程名
%c{1} =>输出日志信息所属的类目,通常就是所在类的全名
%L =>输出代码中的行号
%m =>输出代码中指定的消息,产生的日志具体信息
%n =>输出一个回车换行符,Windows平台为"\r\n",Unix平台为"\n"输出日志信息换行
-->
<Property name="pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} %5p %t %c{1}:%L - %m%n</Property>
<!-- ■■■日志输出文件夹【不同项目在同一个目录下时,用日志文件夹区分不同项目日志】 -->
<Property name="logDir">clientLogs/</Property>
</Properties>
<Loggers>
<Root level="INFO">
<AppenderRef ref="console"/>
<AppenderRef ref="asyncInfoLog"/>
<AppenderRef ref="asyncLogError"/>
</Root>
</Loggers>
<Appenders>
<!-- 定义输出到控制台 -->
<Console name="console" target="SYSTEM_OUT" follow="true">
<!--控制台只输出level及以上级别的信息-->
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>${pattern}</Pattern>
</PatternLayout>
</Console>
<!-- 同一来源的Appender可以定义多个RollingFile,定义按天存储日志 -->
<!-- INFO日志 -->
<RollingFile name="rolling_file_info" fileName="${logDir}/info_client.log"
filePattern="${logDir}/info_client_%d{yyyy-MM-dd}.log">
<Filters>
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<Pattern>${pattern}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<!-- 日志保留策略,配置只保留180天 -->
<DefaultRolloverStrategy>
<Delete basePath="${logDir}/" maxDepth="1">
<IfFileName glob="info_client_*.log"/>
<IfLastModified age="180d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<!-- ERROR日志 -->
<RollingFile name="rolling_file_error" fileName="${logDir}/error_client.log"
filePattern="${logDir}/error_client_%d{yyyy-MM-dd}.log">
<Filters>
<ThresholdFilter level="FATAL" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<Pattern>${pattern}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<!-- 日志保留策略,配置只保留180天 -->
<DefaultRolloverStrategy>
<Delete basePath="${logDir}/" maxDepth="1">
<IfFileName glob="error_client_*.log"/>
<IfLastModified age="180d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<Async name="asyncInfoLog" includeLocation="true">
<AppenderRef ref="rolling_file_info"/>
</Async>
<Async name="asyncLogError" includeLocation="true">
<AppenderRef ref="rolling_file_error"/>
</Async>
</Appenders>
</Configuration>
●registry.conf
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "file"
loadBalance = "RandomLoadBalance"
loadBalanceVirtualNodes = 10
nacos {
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = ""
cluster = "default"
username = ""
password = ""
}
eureka {
serviceUrl = "http://localhost:8761/eureka"
application = "default"
weight = "1"
}
redis {
serverAddr = "localhost:6379"
db = 0
password = ""
cluster = "default"
timeout = 0
}
zk {
cluster = "default"
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
}
consul {
cluster = "default"
serverAddr = "127.0.0.1:8500"
}
etcd3 {
cluster = "default"
serverAddr = "http://localhost:2379"
}
sofa {
serverAddr = "127.0.0.1:9603"
application = "default"
region = "DEFAULT_ZONE"
datacenter = "DefaultDataCenter"
cluster = "default"
group = "SEATA_GROUP"
addressWaitTime = "3000"
}
file {
name = "file.conf"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "file"
nacos {
serverAddr = "127.0.0.1:8848"
namespace = ""
group = "SEATA_GROUP"
username = ""
password = ""
}
consul {
serverAddr = "127.0.0.1:8500"
}
apollo {
appId = "seata-server"
apolloMeta = "http://192.168.1.204:8801"
namespace = "application"
apolloAccesskeySecret = ""
}
zk {
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
}
etcd3 {
serverAddr = "http://localhost:2379"
}
file {
name = "file.conf"
}
}
●pom.xml
<?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 https://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.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com</groupId>
<artifactId>istio-client</artifactId>
<version>1.0</version>
<name>istio-client</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
<!-- 分布式事务 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2.2.6.RELEASE</version>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.4.1</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
★3.2.istio-service1■■■■■■
1.项目结构
●SeataConfig.java
package com.istioservice1.config;
import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import io.seata.spring.annotation.GlobalTransactionScanner;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
@Configuration
public class SeataConfig {
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.driverClassName}")
private String driverClassName;
@Bean
@Primary
public DruidDataSource druidDataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
druidDataSource.setDriverClassName(driverClassName);
// 初始连接数
druidDataSource.setInitialSize(5);
// 最小连接池数量
druidDataSource.setMinIdle(10);
// 最大连接池数量
druidDataSource.setMaxActive(20);
// 配置获取连接等待超时的时间
druidDataSource.setMaxWait(60000);
// 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
druidDataSource.setTimeBetweenEvictionRunsMillis(60000);
// 配置一个连接在池中最小生存的时间,单位是毫秒
druidDataSource.setMinEvictableIdleTimeMillis(300000);
// 配置一个连接在池中最大生存的时间,单位是毫秒
druidDataSource.setMaxEvictableIdleTimeMillis(900000);
// 配置检测连接是否有效
druidDataSource.setValidationQuery("select 'x'");
druidDataSource.setTestWhileIdle(true);
druidDataSource.setTestOnBorrow(false);
druidDataSource.setTestOnReturn(false);
// druidDataSource.setRemoveAbandoned(true);
// druidDataSource.setRemoveAbandonedTimeout(1800);
// druidDataSource.setLogAbandoned(true);
return druidDataSource;
}
@Bean
public DataSourceProxy dataSourceProxy(DataSource druidDataSource) {
return new DataSourceProxy(druidDataSource);
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSourceProxy);
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:/mybatis/mapper/*.xml"));
factoryBean.setTransactionFactory(new JdbcTransactionFactory());
return factoryBean.getObject();
}
@Bean
public GlobalTransactionScanner globalTransactionScanner() {
return new GlobalTransactionScanner("istioService1-gts-seata", "istio_tx_group");
}
}
●Test1Controller.java
package com.istioservice1.controller;
import com.istioservice1.entity.Test1;
import com.istioservice1.service.Test1Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
@RestController
@RequestMapping("/test1")
public class Test1Controller {
private Logger logger = LoggerFactory.getLogger(Test1Controller.class);
@Autowired
Test1Service test1Service;
@RequestMapping("/getTest")
public String getTest(){
logger.info("$$$$$$$$$$$$getTest");
return "hello";
}
@RequestMapping("/getTest1")
public String getTest1(){
logger.info("$$$$$$$$$$$$getTest1");
String ip = getIp();
Test1 test1=test1Service.getTest1ByKey(1);
return "istio-service1 ip=" + ip + "|name = " + test1.getName();
}
@RequestMapping("/insertTest1")
public String insertTest1(){
logger.info("$$$$$$$$$$$$insertTest1");
test1Service.insertTest1();
return "ok";
}
public String getIp(){
String ipAdd = "";
try{
Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces();
InetAddress ip = null;
while (allNetInterfaces.hasMoreElements())
{
NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
System.out.println(netInterface.getName());
Enumeration addresses = netInterface.getInetAddresses();
while (addresses.hasMoreElements())
{
ip = (InetAddress) addresses.nextElement();
if (ip != null && ip instanceof Inet4Address)
{
ipAdd = ip.getHostAddress();
System.out.println("本机的IP = " + ip.getHostAddress());
}
}
}
}catch (Exception e){
e.printStackTrace();
}
return ipAdd;
}
}
●Test1Mapper.java
package com.istioservice1.dao;
import com.istioservice1.entity.Test1;
import com.istioservice1.entity.Test1Example;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface Test1Mapper {
int deleteByExample(Test1Example example);
int deleteByPrimaryKey(Integer id);
int insert(Test1 record);
int insertSelective(Test1 record);
List<Test1> selectByExample(Test1Example example);
Test1 selectByPrimaryKey(Integer id);
int updateByExampleSelective(@Param("record") Test1 record, @Param("example") Test1Example example);
int updateByExample(@Param("record") Test1 record, @Param("example") Test1Example example);
int updateByPrimaryKeySelective(Test1 record);
int updateByPrimaryKey(Test1 record);
}
●Test4Mapper.java
package com.istioservice1.dao;
import com.istioservice1.entity.Test4;
import com.istioservice1.entity.Test4Example;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface Test4Mapper {
int deleteByExample(Test4Example example);
int deleteByPrimaryKey(Integer id);
int insert(Test4 record);
int insertSelective(Test4 record);
List<Test4> selectByExample(Test4Example example);
Test4 selectByPrimaryKey(Integer id);
int updateByExampleSelective(@Param("record") Test4 record, @Param("example") Test4Example example);
int updateByExample(@Param("record") Test4 record, @Param("example") Test4Example example);
int updateByPrimaryKeySelective(Test4 record);
int updateByPrimaryKey(Test4 record);
}
●Test1.java
package com.istioservice1.entity;
public class Test1 {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
●Test1Example.java
package com.istioservice1.entity;
import java.util.ArrayList;
import java.util.List;
public class Test1Example {
protected String orderByClause;
protected boolean distinct;
protected List<Criteria> oredCriteria;
public Test1Example() {
oredCriteria = new ArrayList<Criteria>();
}
public void setOrderByClause(String orderByClause) {
this.orderByClause = orderByClause;
}
public String getOrderByClause() {
return orderByClause;
}
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public boolean isDistinct() {
return distinct;
}
public List<Criteria> getOredCriteria() {
return oredCriteria;
}
public void or(Criteria criteria) {
oredCriteria.add(criteria);
}
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
public Criteria createCriteria() {
Criteria criteria = createCriteriaInternal();
if (oredCriteria.size() == 0) {
oredCriteria.add(criteria);
}
return criteria;
}
protected Criteria createCriteriaInternal() {
Criteria criteria = new Criteria();
return criteria;
}
public void clear() {
oredCriteria.clear();
orderByClause = null;
distinct = false;
}
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
super();
criteria = new ArrayList<Criterion>();
}
public boolean isValid() {
return criteria.size() > 0;
}
public List<Criterion> getAllCriteria() {
return criteria;
}
public List<Criterion> getCriteria() {
return criteria;
}
protected void addCriterion(String condition) {
if (condition == null) {
throw new RuntimeException("Value for condition cannot be null");
}
criteria.add(new Criterion(condition));
}
protected void addCriterion(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value));
}
protected void addCriterion(String condition, Object value1, Object value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value1, value2));
}
public Criteria andIdIsNull() {
addCriterion("id is null");
return (Criteria) this;
}
public Criteria andIdIsNotNull() {
addCriterion("id is not null");
return (Criteria) this;
}
public Criteria andIdEqualTo(Integer value) {
addCriterion("id =", value, "id");
return (Criteria) this;
}
public Criteria andIdNotEqualTo(Integer value) {
addCriterion("id <>", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThan(Integer value) {
addCriterion("id >", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThanOrEqualTo(Integer value) {
addCriterion("id >=", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThan(Integer value) {
addCriterion("id <", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThanOrEqualTo(Integer value) {
addCriterion("id <=", value, "id");
return (Criteria) this;
}
public Criteria andIdIn(List<Integer> values) {
addCriterion("id in", values, "id");
return (Criteria) this;
}
public Criteria andIdNotIn(List<Integer> values) {
addCriterion("id not in", values, "id");
return (Criteria) this;
}
public Criteria andIdBetween(Integer value1, Integer value2) {
addCriterion("id between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andIdNotBetween(Integer value1, Integer value2) {
addCriterion("id not between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andNameIsNull() {
addCriterion("name is null");
return (Criteria) this;
}
public Criteria andNameIsNotNull() {
addCriterion("name is not null");
return (Criteria) this;
}
public Criteria andNameEqualTo(String value) {
addCriterion("name =", value, "name");
return (Criteria) this;
}
public Criteria andNameNotEqualTo(String value) {
addCriterion("name <>", value, "name");
return (Criteria) this;
}
public Criteria andNameGreaterThan(String value) {
addCriterion("name >", value, "name");
return (Criteria) this;
}
public Criteria andNameGreaterThanOrEqualTo(String value) {
addCriterion("name >=", value, "name");
return (Criteria) this;
}
public Criteria andNameLessThan(String value) {
addCriterion("name <", value, "name");
return (Criteria) this;
}
public Criteria andNameLessThanOrEqualTo(String value) {
addCriterion("name <=", value, "name");
return (Criteria) this;
}
public Criteria andNameLike(String value) {
addCriterion("name like", value, "name");
return (Criteria) this;
}
public Criteria andNameNotLike(String value) {
addCriterion("name not like", value, "name");
return (Criteria) this;
}
public Criteria andNameIn(List<String> values) {
addCriterion("name in", values, "name");
return (Criteria) this;
}
public Criteria andNameNotIn(List<String> values) {
addCriterion("name not in", values, "name");
return (Criteria) this;
}
public Criteria andNameBetween(String value1, String value2) {
addCriterion("name between", value1, value2, "name");
return (Criteria) this;
}
public Criteria andNameNotBetween(String value1, String value2) {
addCriterion("name not between", value1, value2, "name");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {
protected Criteria() {
super();
}
}
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.typeHandler = typeHandler;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value) {
this(condition, value, null);
}
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.typeHandler = typeHandler;
this.betweenValue = true;
}
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
}
}
●Test4.java
package com.istioservice1.entity;
public class Test4 {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
●Test4Example.java
package com.istioservice1.entity;
import java.util.ArrayList;
import java.util.List;
public class Test4Example {
protected String orderByClause;
protected boolean distinct;
protected List<Criteria> oredCriteria;
public Test4Example() {
oredCriteria = new ArrayList<Criteria>();
}
public void setOrderByClause(String orderByClause) {
this.orderByClause = orderByClause;
}
public String getOrderByClause() {
return orderByClause;
}
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public boolean isDistinct() {
return distinct;
}
public List<Criteria> getOredCriteria() {
return oredCriteria;
}
public void or(Criteria criteria) {
oredCriteria.add(criteria);
}
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
public Criteria createCriteria() {
Criteria criteria = createCriteriaInternal();
if (oredCriteria.size() == 0) {
oredCriteria.add(criteria);
}
return criteria;
}
protected Criteria createCriteriaInternal() {
Criteria criteria = new Criteria();
return criteria;
}
public void clear() {
oredCriteria.clear();
orderByClause = null;
distinct = false;
}
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
super();
criteria = new ArrayList<Criterion>();
}
public boolean isValid() {
return criteria.size() > 0;
}
public List<Criterion> getAllCriteria() {
return criteria;
}
public List<Criterion> getCriteria() {
return criteria;
}
protected void addCriterion(String condition) {
if (condition == null) {
throw new RuntimeException("Value for condition cannot be null");
}
criteria.add(new Criterion(condition));
}
protected void addCriterion(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value));
}
protected void addCriterion(String condition, Object value1, Object value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value1, value2));
}
public Criteria andIdIsNull() {
addCriterion("id is null");
return (Criteria) this;
}
public Criteria andIdIsNotNull() {
addCriterion("id is not null");
return (Criteria) this;
}
public Criteria andIdEqualTo(Integer value) {
addCriterion("id =", value, "id");
return (Criteria) this;
}
public Criteria andIdNotEqualTo(Integer value) {
addCriterion("id <>", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThan(Integer value) {
addCriterion("id >", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThanOrEqualTo(Integer value) {
addCriterion("id >=", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThan(Integer value) {
addCriterion("id <", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThanOrEqualTo(Integer value) {
addCriterion("id <=", value, "id");
return (Criteria) this;
}
public Criteria andIdIn(List<Integer> values) {
addCriterion("id in", values, "id");
return (Criteria) this;
}
public Criteria andIdNotIn(List<Integer> values) {
addCriterion("id not in", values, "id");
return (Criteria) this;
}
public Criteria andIdBetween(Integer value1, Integer value2) {
addCriterion("id between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andIdNotBetween(Integer value1, Integer value2) {
addCriterion("id not between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andNameIsNull() {
addCriterion("name is null");
return (Criteria) this;
}
public Criteria andNameIsNotNull() {
addCriterion("name is not null");
return (Criteria) this;
}
public Criteria andNameEqualTo(String value) {
addCriterion("name =", value, "name");
return (Criteria) this;
}
public Criteria andNameNotEqualTo(String value) {
addCriterion("name <>", value, "name");
return (Criteria) this;
}
public Criteria andNameGreaterThan(String value) {
addCriterion("name >", value, "name");
return (Criteria) this;
}
public Criteria andNameGreaterThanOrEqualTo(String value) {
addCriterion("name >=", value, "name");
return (Criteria) this;
}
public Criteria andNameLessThan(String value) {
addCriterion("name <", value, "name");
return (Criteria) this;
}
public Criteria andNameLessThanOrEqualTo(String value) {
addCriterion("name <=", value, "name");
return (Criteria) this;
}
public Criteria andNameLike(String value) {
addCriterion("name like", value, "name");
return (Criteria) this;
}
public Criteria andNameNotLike(String value) {
addCriterion("name not like", value, "name");
return (Criteria) this;
}
public Criteria andNameIn(List<String> values) {
addCriterion("name in", values, "name");
return (Criteria) this;
}
public Criteria andNameNotIn(List<String> values) {
addCriterion("name not in", values, "name");
return (Criteria) this;
}
public Criteria andNameBetween(String value1, String value2) {
addCriterion("name between", value1, value2, "name");
return (Criteria) this;
}
public Criteria andNameNotBetween(String value1, String value2) {
addCriterion("name not between", value1, value2, "name");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {
protected Criteria() {
super();
}
}
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.typeHandler = typeHandler;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value) {
this(condition, value, null);
}
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.typeHandler = typeHandler;
this.betweenValue = true;
}
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
}
}
●Test1Service.java
package com.istioservice1.service;
import com.istioservice1.dao.Test1Mapper;
import com.istioservice1.entity.Test1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional(rollbackFor = Exception.class)
public class Test1Service {
@Autowired
Test1Mapper test1Mapper;
public Test1 getTest1ByKey(int id){
Test1 test1 = test1Mapper.selectByPrimaryKey(id);
return test1;
}
public void insertTest1(){
Test1 test1 = new Test1();
test1.setId(99);
test1.setName("liutao");
test1Mapper.insert(test1);
}
}
●IstioSvc1App.java
package com.istioservice1;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.istioservice1.dao")
@SpringBootApplication
public class IstioSvc1App {
public static void main(String[] args) {
SpringApplication.run(IstioSvc1App.class, args);
}
}
●Test1Mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.istioservice1.dao.Test1Mapper">
<resultMap id="BaseResultMap" type="com.istioservice1.entity.Test1">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
</resultMap>
<sql id="Example_Where_Clause">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<where>
<foreach collection="example.oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
id, name
</sql>
<select id="selectByExample" parameterType="com.istioservice1.entity.Test1Example" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
select
<if test="distinct">
distinct
</if>
'true' as QUERYID,
<include refid="Base_Column_List" />
from test1
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
select
<include refid="Base_Column_List" />
from test1
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
delete from test1
where id = #{id,jdbcType=INTEGER}
</delete>
<delete id="deleteByExample" parameterType="com.istioservice1.entity.Test1Example">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
delete from test1
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="com.istioservice1.entity.Test1">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
insert into test1 (id, name)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.istioservice1.entity.Test1">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
insert into test1
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="name != null">
name,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=INTEGER},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<update id="updateByExampleSelective" parameterType="map">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test1
<set>
<if test="record.id != null">
id = #{record.id,jdbcType=INTEGER},
</if>
<if test="record.name != null">
name = #{record.name,jdbcType=VARCHAR},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test1
set id = #{record.id,jdbcType=INTEGER},
name = #{record.name,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="com.istioservice1.entity.Test1">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test1
<set>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.istioservice1.entity.Test1">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test1
set name = #{name,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>
</mapper>
●Test4Mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.istioservice1.dao.Test4Mapper">
<resultMap id="BaseResultMap" type="com.istioservice1.entity.Test4">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
</resultMap>
<sql id="Example_Where_Clause">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<where>
<foreach collection="example.oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
id, name
</sql>
<select id="selectByExample" parameterType="com.istioservice1.entity.Test4Example" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
select
<if test="distinct">
distinct
</if>
'true' as QUERYID,
<include refid="Base_Column_List" />
from test4
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
select
<include refid="Base_Column_List" />
from test4
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
delete from test4
where id = #{id,jdbcType=INTEGER}
</delete>
<delete id="deleteByExample" parameterType="com.istioservice1.entity.Test4Example">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
delete from test4
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="com.istioservice1.entity.Test4">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
insert into test4 (id, name)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.istioservice1.entity.Test4">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
insert into test4
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="name != null">
name,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=INTEGER},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<update id="updateByExampleSelective" parameterType="map">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test4
<set>
<if test="record.id != null">
id = #{record.id,jdbcType=INTEGER},
</if>
<if test="record.name != null">
name = #{record.name,jdbcType=VARCHAR},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test4
set id = #{record.id,jdbcType=INTEGER},
name = #{record.name,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="com.istioservice1.entity.Test4">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test4
<set>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.istioservice1.entity.Test4">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test4
set name = #{name,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>
</mapper>
●application.properties
server.port=8081
#本地测试用
spring.datasource.url=jdbc:postgresql://2.0.0.1:5432/test1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
#k8s测试用
#spring.datasource.url=jdbc:postgresql://10.108.206.185:5432/test1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driverClassName=org.postgresql.Driver
#mybatis.config-location=classpath:mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mybatis.type-aliases-package=com.istioservice1.entity
●file.conf
transport {
# tcp udt unix-domain-socket
type = "TCP"
#NIO NATIVE
server = "NIO"
#enable heartbeat
heartbeat = true
# the client batch send request enable
enableClientBatchSendRequest = true
#thread factory for netty
threadFactory {
bossThreadPrefix = "NettyBoss"
workerThreadPrefix = "NettyServerNIOWorker"
serverExecutorThread-prefix = "NettyServerBizHandler"
shareBossWorker = false
clientSelectorThreadPrefix = "NettyClientSelector"
clientSelectorThreadSize = 1
clientWorkerThreadPrefix = "NettyClientWorkerThread"
# netty boss thread size,will not be used for UDT
bossThreadSize = 1
#auto default pin or 8
workerThreadSize = "default"
}
shutdown {
# when destroy server, wait seconds
wait = 3
}
serialization = "seata"
compressor = "none"
}
service {
#transaction service group mapping
vgroupMapping.istio_tx_group = "default"
#only support when registry.type=file, please don't set multiple addresses
#■■■■■■■■■■■■■ seata 地址设置 start ■■■■■■■■■■■■■
default.grouplist = "172.22.70.72:8091"
#■■■■■■■■■■■■■ seata 地址设置 end ■■■■■■■■■■■■■
#degrade, current not support
enableDegrade = false
#disable seata
disableGlobalTransaction = false
}
client {
rm {
asyncCommitBufferLimit = 10000
lock {
retryInterval = 10
retryTimes = 30
retryPolicyBranchRollbackOnConflict = true
}
reportRetryCount = 5
tableMetaCheckEnable = false
reportSuccessEnable = false
}
tm {
commitRetryCount = 5
rollbackRetryCount = 5
}
undo {
dataValidation = true
logSerialization = "jackson"
logTable = "undo_log"
}
log {
exceptionRate = 100
}
}
●log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<!-- ■■■■■ 要使这个配置生效,需要pom中排除掉spring-boot-starter-logging ■■■■■ -->
<!--全局参数-->
<Properties>
<!--
%d{yyyy-MM-dd HH:mm:ss.SSS} =>格式化时间 2020-01-21 14:03:53.858
%5p =>输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%t =>输出产生该日志事件的线程名
%c{1} =>输出日志信息所属的类目,通常就是所在类的全名
%L =>输出代码中的行号
%m =>输出代码中指定的消息,产生的日志具体信息
%n =>输出一个回车换行符,Windows平台为"\r\n",Unix平台为"\n"输出日志信息换行
-->
<Property name="pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} %5p %t %c{1}:%L - %m%n</Property>
<!-- ■■■日志输出文件夹【不同项目在同一个目录下时,用日志文件夹区分不同项目日志】 -->
<Property name="logDir">service1Logs/</Property>
</Properties>
<Loggers>
<Root level="INFO">
<AppenderRef ref="console"/>
<AppenderRef ref="asyncInfoLog"/>
<AppenderRef ref="asyncLogError"/>
</Root>
</Loggers>
<Appenders>
<!-- 定义输出到控制台 -->
<Console name="console" target="SYSTEM_OUT" follow="true">
<!--控制台只输出level及以上级别的信息-->
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>${pattern}</Pattern>
</PatternLayout>
</Console>
<!-- 同一来源的Appender可以定义多个RollingFile,定义按天存储日志 -->
<!-- INFO日志 -->
<RollingFile name="rolling_file_info" fileName="${logDir}/info_service1.log"
filePattern="${logDir}/info_service1_%d{yyyy-MM-dd}.log">
<Filters>
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<Pattern>${pattern}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<!-- 日志保留策略,配置只保留180天 -->
<DefaultRolloverStrategy>
<Delete basePath="${logDir}/" maxDepth="1">
<IfFileName glob="info_service1_*.log"/>
<IfLastModified age="180d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<!-- ERROR日志 -->
<RollingFile name="rolling_file_error" fileName="${logDir}/error_service1.log"
filePattern="${logDir}/error_service1_%d{yyyy-MM-dd}.log">
<Filters>
<ThresholdFilter level="FATAL" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<Pattern>${pattern}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<!-- 日志保留策略,配置只保留180天 -->
<DefaultRolloverStrategy>
<Delete basePath="${logDir}/" maxDepth="1">
<IfFileName glob="error_service1_*.log"/>
<IfLastModified age="180d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<Async name="asyncInfoLog" includeLocation="true">
<AppenderRef ref="rolling_file_info"/>
</Async>
<Async name="asyncLogError" includeLocation="true">
<AppenderRef ref="rolling_file_error"/>
</Async>
</Appenders>
</Configuration>
●registry.conf
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "file"
loadBalance = "RandomLoadBalance"
loadBalanceVirtualNodes = 10
nacos {
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = ""
cluster = "default"
username = ""
password = ""
}
eureka {
serviceUrl = "http://localhost:8761/eureka"
application = "default"
weight = "1"
}
redis {
serverAddr = "localhost:6379"
db = 0
password = ""
cluster = "default"
timeout = 0
}
zk {
cluster = "default"
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
}
consul {
cluster = "default"
serverAddr = "127.0.0.1:8500"
}
etcd3 {
cluster = "default"
serverAddr = "http://localhost:2379"
}
sofa {
serverAddr = "127.0.0.1:9603"
application = "default"
region = "DEFAULT_ZONE"
datacenter = "DefaultDataCenter"
cluster = "default"
group = "SEATA_GROUP"
addressWaitTime = "3000"
}
file {
name = "file.conf"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "file"
nacos {
serverAddr = "127.0.0.1:8848"
namespace = ""
group = "SEATA_GROUP"
username = ""
password = ""
}
consul {
serverAddr = "127.0.0.1:8500"
}
apollo {
appId = "seata-server"
apolloMeta = "http://192.168.1.204:8801"
namespace = "application"
apolloAccesskeySecret = ""
}
zk {
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
}
etcd3 {
serverAddr = "http://localhost:2379"
}
file {
name = "file.conf"
}
}
●pom.xml
<?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 https://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.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com</groupId>
<artifactId>istio-service1</artifactId>
<version>1.0</version>
<name>istio-service1</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- 分布式事务 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2.2.6.RELEASE</version>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.4.1</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
★3.3.istio-service2■■■■■■
1.项目结构
●SeataConfig.java
package com.istioservice2.config;
import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import io.seata.spring.annotation.GlobalTransactionScanner;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
@Configuration
public class SeataConfig {
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.driverClassName}")
private String driverClassName;
@Bean
@Primary
public DruidDataSource druidDataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
druidDataSource.setDriverClassName(driverClassName);
// 初始连接数
druidDataSource.setInitialSize(5);
// 最小连接池数量
druidDataSource.setMinIdle(10);
// 最大连接池数量
druidDataSource.setMaxActive(20);
// 配置获取连接等待超时的时间
druidDataSource.setMaxWait(60000);
// 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
druidDataSource.setTimeBetweenEvictionRunsMillis(60000);
// 配置一个连接在池中最小生存的时间,单位是毫秒
druidDataSource.setMinEvictableIdleTimeMillis(300000);
// 配置一个连接在池中最大生存的时间,单位是毫秒
druidDataSource.setMaxEvictableIdleTimeMillis(900000);
// 配置检测连接是否有效
druidDataSource.setValidationQuery("select 'x'");
druidDataSource.setTestWhileIdle(true);
druidDataSource.setTestOnBorrow(false);
druidDataSource.setTestOnReturn(false);
// druidDataSource.setRemoveAbandoned(true);
// druidDataSource.setRemoveAbandonedTimeout(1800);
// druidDataSource.setLogAbandoned(true);
return druidDataSource;
}
@Bean
public DataSourceProxy dataSourceProxy(DataSource druidDataSource) {
return new DataSourceProxy(druidDataSource);
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSourceProxy);
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:/mybatis/mapper/*.xml"));
factoryBean.setTransactionFactory(new JdbcTransactionFactory());
return factoryBean.getObject();
}
@Bean
public GlobalTransactionScanner globalTransactionScanner() {
return new GlobalTransactionScanner("istioService2-gts-seata", "istio_tx_group");
}
}
●Test2Controller.java
package com.istioservice2.controller;
import com.istioservice2.entity.Test1;
import com.istioservice2.service.Test2Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test2")
public class Test2Controller {
private Logger logger = LoggerFactory.getLogger(Test2Controller.class);
@Autowired
Test2Service test2Service;
@RequestMapping("/getTest2")
public String getTest2(){
logger.info("%%%%%%%%%%%%%%getTest2");
Test1 test1=test2Service.getTest1ByKey(2);
return "istio-service2" + "| name =" + test1.getName();
}
@RequestMapping("/insertTest4")
public String insertTest4(){
logger.info("%%%%%%%%%%%%%%insertTest4");
test2Service.insertTest4();
return "ok";
}
}
●Test1Mapper.java
package com.istioservice2.dao;
import com.istioservice2.entity.Test1;
import com.istioservice2.entity.Test1Example;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface Test1Mapper {
int deleteByExample(Test1Example example);
int deleteByPrimaryKey(Integer id);
int insert(Test1 record);
int insertSelective(Test1 record);
List<Test1> selectByExample(Test1Example example);
Test1 selectByPrimaryKey(Integer id);
int updateByExampleSelective(@Param("record") Test1 record, @Param("example") Test1Example example);
int updateByExample(@Param("record") Test1 record, @Param("example") Test1Example example);
int updateByPrimaryKeySelective(Test1 record);
int updateByPrimaryKey(Test1 record);
}
●Test4Mapper.java
package com.istioservice2.dao;
import com.istioservice2.entity.Test4;
import com.istioservice2.entity.Test4Example;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface Test4Mapper {
int deleteByExample(Test4Example example);
int deleteByPrimaryKey(Integer id);
int insert(Test4 record);
int insertSelective(Test4 record);
List<Test4> selectByExample(Test4Example example);
Test4 selectByPrimaryKey(Integer id);
int updateByExampleSelective(@Param("record") Test4 record, @Param("example") Test4Example example);
int updateByExample(@Param("record") Test4 record, @Param("example") Test4Example example);
int updateByPrimaryKeySelective(Test4 record);
int updateByPrimaryKey(Test4 record);
}
●Test1.java
package com.istioservice2.entity;
public class Test1 {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
●Test1Example.java
package com.istioservice2.entity;
import java.util.ArrayList;
import java.util.List;
public class Test1Example {
protected String orderByClause;
protected boolean distinct;
protected List<Criteria> oredCriteria;
public Test1Example() {
oredCriteria = new ArrayList<Criteria>();
}
public void setOrderByClause(String orderByClause) {
this.orderByClause = orderByClause;
}
public String getOrderByClause() {
return orderByClause;
}
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public boolean isDistinct() {
return distinct;
}
public List<Criteria> getOredCriteria() {
return oredCriteria;
}
public void or(Criteria criteria) {
oredCriteria.add(criteria);
}
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
public Criteria createCriteria() {
Criteria criteria = createCriteriaInternal();
if (oredCriteria.size() == 0) {
oredCriteria.add(criteria);
}
return criteria;
}
protected Criteria createCriteriaInternal() {
Criteria criteria = new Criteria();
return criteria;
}
public void clear() {
oredCriteria.clear();
orderByClause = null;
distinct = false;
}
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
super();
criteria = new ArrayList<Criterion>();
}
public boolean isValid() {
return criteria.size() > 0;
}
public List<Criterion> getAllCriteria() {
return criteria;
}
public List<Criterion> getCriteria() {
return criteria;
}
protected void addCriterion(String condition) {
if (condition == null) {
throw new RuntimeException("Value for condition cannot be null");
}
criteria.add(new Criterion(condition));
}
protected void addCriterion(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value));
}
protected void addCriterion(String condition, Object value1, Object value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value1, value2));
}
public Criteria andIdIsNull() {
addCriterion("id is null");
return (Criteria) this;
}
public Criteria andIdIsNotNull() {
addCriterion("id is not null");
return (Criteria) this;
}
public Criteria andIdEqualTo(Integer value) {
addCriterion("id =", value, "id");
return (Criteria) this;
}
public Criteria andIdNotEqualTo(Integer value) {
addCriterion("id <>", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThan(Integer value) {
addCriterion("id >", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThanOrEqualTo(Integer value) {
addCriterion("id >=", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThan(Integer value) {
addCriterion("id <", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThanOrEqualTo(Integer value) {
addCriterion("id <=", value, "id");
return (Criteria) this;
}
public Criteria andIdIn(List<Integer> values) {
addCriterion("id in", values, "id");
return (Criteria) this;
}
public Criteria andIdNotIn(List<Integer> values) {
addCriterion("id not in", values, "id");
return (Criteria) this;
}
public Criteria andIdBetween(Integer value1, Integer value2) {
addCriterion("id between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andIdNotBetween(Integer value1, Integer value2) {
addCriterion("id not between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andNameIsNull() {
addCriterion("name is null");
return (Criteria) this;
}
public Criteria andNameIsNotNull() {
addCriterion("name is not null");
return (Criteria) this;
}
public Criteria andNameEqualTo(String value) {
addCriterion("name =", value, "name");
return (Criteria) this;
}
public Criteria andNameNotEqualTo(String value) {
addCriterion("name <>", value, "name");
return (Criteria) this;
}
public Criteria andNameGreaterThan(String value) {
addCriterion("name >", value, "name");
return (Criteria) this;
}
public Criteria andNameGreaterThanOrEqualTo(String value) {
addCriterion("name >=", value, "name");
return (Criteria) this;
}
public Criteria andNameLessThan(String value) {
addCriterion("name <", value, "name");
return (Criteria) this;
}
public Criteria andNameLessThanOrEqualTo(String value) {
addCriterion("name <=", value, "name");
return (Criteria) this;
}
public Criteria andNameLike(String value) {
addCriterion("name like", value, "name");
return (Criteria) this;
}
public Criteria andNameNotLike(String value) {
addCriterion("name not like", value, "name");
return (Criteria) this;
}
public Criteria andNameIn(List<String> values) {
addCriterion("name in", values, "name");
return (Criteria) this;
}
public Criteria andNameNotIn(List<String> values) {
addCriterion("name not in", values, "name");
return (Criteria) this;
}
public Criteria andNameBetween(String value1, String value2) {
addCriterion("name between", value1, value2, "name");
return (Criteria) this;
}
public Criteria andNameNotBetween(String value1, String value2) {
addCriterion("name not between", value1, value2, "name");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {
protected Criteria() {
super();
}
}
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.typeHandler = typeHandler;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value) {
this(condition, value, null);
}
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.typeHandler = typeHandler;
this.betweenValue = true;
}
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
}
}
●Test4.java
package com.istioservice2.entity;
public class Test4 {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
●Test4Example.java
package com.istioservice2.entity;
import java.util.ArrayList;
import java.util.List;
public class Test4Example {
protected String orderByClause;
protected boolean distinct;
protected List<Criteria> oredCriteria;
public Test4Example() {
oredCriteria = new ArrayList<Criteria>();
}
public void setOrderByClause(String orderByClause) {
this.orderByClause = orderByClause;
}
public String getOrderByClause() {
return orderByClause;
}
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public boolean isDistinct() {
return distinct;
}
public List<Criteria> getOredCriteria() {
return oredCriteria;
}
public void or(Criteria criteria) {
oredCriteria.add(criteria);
}
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
public Criteria createCriteria() {
Criteria criteria = createCriteriaInternal();
if (oredCriteria.size() == 0) {
oredCriteria.add(criteria);
}
return criteria;
}
protected Criteria createCriteriaInternal() {
Criteria criteria = new Criteria();
return criteria;
}
public void clear() {
oredCriteria.clear();
orderByClause = null;
distinct = false;
}
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
super();
criteria = new ArrayList<Criterion>();
}
public boolean isValid() {
return criteria.size() > 0;
}
public List<Criterion> getAllCriteria() {
return criteria;
}
public List<Criterion> getCriteria() {
return criteria;
}
protected void addCriterion(String condition) {
if (condition == null) {
throw new RuntimeException("Value for condition cannot be null");
}
criteria.add(new Criterion(condition));
}
protected void addCriterion(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value));
}
protected void addCriterion(String condition, Object value1, Object value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value1, value2));
}
public Criteria andIdIsNull() {
addCriterion("id is null");
return (Criteria) this;
}
public Criteria andIdIsNotNull() {
addCriterion("id is not null");
return (Criteria) this;
}
public Criteria andIdEqualTo(Integer value) {
addCriterion("id =", value, "id");
return (Criteria) this;
}
public Criteria andIdNotEqualTo(Integer value) {
addCriterion("id <>", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThan(Integer value) {
addCriterion("id >", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThanOrEqualTo(Integer value) {
addCriterion("id >=", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThan(Integer value) {
addCriterion("id <", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThanOrEqualTo(Integer value) {
addCriterion("id <=", value, "id");
return (Criteria) this;
}
public Criteria andIdIn(List<Integer> values) {
addCriterion("id in", values, "id");
return (Criteria) this;
}
public Criteria andIdNotIn(List<Integer> values) {
addCriterion("id not in", values, "id");
return (Criteria) this;
}
public Criteria andIdBetween(Integer value1, Integer value2) {
addCriterion("id between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andIdNotBetween(Integer value1, Integer value2) {
addCriterion("id not between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andNameIsNull() {
addCriterion("name is null");
return (Criteria) this;
}
public Criteria andNameIsNotNull() {
addCriterion("name is not null");
return (Criteria) this;
}
public Criteria andNameEqualTo(String value) {
addCriterion("name =", value, "name");
return (Criteria) this;
}
public Criteria andNameNotEqualTo(String value) {
addCriterion("name <>", value, "name");
return (Criteria) this;
}
public Criteria andNameGreaterThan(String value) {
addCriterion("name >", value, "name");
return (Criteria) this;
}
public Criteria andNameGreaterThanOrEqualTo(String value) {
addCriterion("name >=", value, "name");
return (Criteria) this;
}
public Criteria andNameLessThan(String value) {
addCriterion("name <", value, "name");
return (Criteria) this;
}
public Criteria andNameLessThanOrEqualTo(String value) {
addCriterion("name <=", value, "name");
return (Criteria) this;
}
public Criteria andNameLike(String value) {
addCriterion("name like", value, "name");
return (Criteria) this;
}
public Criteria andNameNotLike(String value) {
addCriterion("name not like", value, "name");
return (Criteria) this;
}
public Criteria andNameIn(List<String> values) {
addCriterion("name in", values, "name");
return (Criteria) this;
}
public Criteria andNameNotIn(List<String> values) {
addCriterion("name not in", values, "name");
return (Criteria) this;
}
public Criteria andNameBetween(String value1, String value2) {
addCriterion("name between", value1, value2, "name");
return (Criteria) this;
}
public Criteria andNameNotBetween(String value1, String value2) {
addCriterion("name not between", value1, value2, "name");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {
protected Criteria() {
super();
}
}
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.typeHandler = typeHandler;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value) {
this(condition, value, null);
}
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.typeHandler = typeHandler;
this.betweenValue = true;
}
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
}
}
●Test2Service.java
package com.istioservice2.service;
import com.istioservice2.dao.Test1Mapper;
import com.istioservice2.dao.Test4Mapper;
import com.istioservice2.entity.Test1;
import com.istioservice2.entity.Test4;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional(rollbackFor = Exception.class)
public class Test2Service {
@Autowired
Test1Mapper test1Mapper;
@Autowired
Test4Mapper test4Mapper;
public Test1 getTest1ByKey(int id){
Test1 test1 = test1Mapper.selectByPrimaryKey(id);
return test1;
}
public void insertTest4(){
Test4 test4 = new Test4();
test4.setId(98);
test4.setName("sharpfire");
test4Mapper.insert(test4);
int i = 1/0;
}
}
●IstioSvc2App.java
package com.istioservice2;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
@MapperScan("com.istioservice2.dao")
@SpringBootApplication
public class IstioSvc2App {
public static void main(String[] args) {
SpringApplication.run(IstioSvc2App.class, args);
}
}
Test1Mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.istioservice2.dao.Test1Mapper">
<resultMap id="BaseResultMap" type="com.istioservice2.entity.Test1">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
</resultMap>
<sql id="Example_Where_Clause">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<where>
<foreach collection="example.oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
id, name
</sql>
<select id="selectByExample" parameterType="com.istioservice2.entity.Test1Example" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
select
<if test="distinct">
distinct
</if>
'true' as QUERYID,
<include refid="Base_Column_List" />
from test1
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
select
<include refid="Base_Column_List" />
from test1
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
delete from test1
where id = #{id,jdbcType=INTEGER}
</delete>
<delete id="deleteByExample" parameterType="com.istioservice2.entity.Test1Example">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
delete from test1
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="com.istioservice2.entity.Test1">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
insert into test1 (id, name)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.istioservice2.entity.Test1">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
insert into test1
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="name != null">
name,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=INTEGER},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<update id="updateByExampleSelective" parameterType="map">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test1
<set>
<if test="record.id != null">
id = #{record.id,jdbcType=INTEGER},
</if>
<if test="record.name != null">
name = #{record.name,jdbcType=VARCHAR},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test1
set id = #{record.id,jdbcType=INTEGER},
name = #{record.name,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="com.istioservice2.entity.Test1">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test1
<set>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.istioservice2.entity.Test1">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test1
set name = #{name,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>
</mapper>
●Test4Mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.istioservice2.dao.Test4Mapper">
<resultMap id="BaseResultMap" type="com.istioservice2.entity.Test4">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
</resultMap>
<sql id="Example_Where_Clause">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<where>
<foreach collection="example.oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
id, name
</sql>
<select id="selectByExample" parameterType="com.istioservice2.entity.Test4Example" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
select
<if test="distinct">
distinct
</if>
'true' as QUERYID,
<include refid="Base_Column_List" />
from test4
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
select
<include refid="Base_Column_List" />
from test4
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
delete from test4
where id = #{id,jdbcType=INTEGER}
</delete>
<delete id="deleteByExample" parameterType="com.istioservice2.entity.Test4Example">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
delete from test4
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="com.istioservice2.entity.Test4">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
insert into test4 (id, name)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.istioservice2.entity.Test4">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
insert into test4
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="name != null">
name,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=INTEGER},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<update id="updateByExampleSelective" parameterType="map">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test4
<set>
<if test="record.id != null">
id = #{record.id,jdbcType=INTEGER},
</if>
<if test="record.name != null">
name = #{record.name,jdbcType=VARCHAR},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test4
set id = #{record.id,jdbcType=INTEGER},
name = #{record.name,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="com.istioservice2.entity.Test4">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test4
<set>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.istioservice2.entity.Test4">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update test4
set name = #{name,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>
</mapper>
●application.properties
server.port=8082
#本地测试用
spring.datasource.url=jdbc:postgresql://2.0.0.1:5432/test1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
#k8s环境用
#spring.datasource.url=jdbc:postgresql://10.108.206.185:5432/test1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driverClassName=org.postgresql.Driver
#mybatis.config-location=classpath:mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mybatis.type-aliases-package=com.istioservice2.entity
●file.conf
transport {
# tcp udt unix-domain-socket
type = "TCP"
#NIO NATIVE
server = "NIO"
#enable heartbeat
heartbeat = true
# the client batch send request enable
enableClientBatchSendRequest = true
#thread factory for netty
threadFactory {
bossThreadPrefix = "NettyBoss"
workerThreadPrefix = "NettyServerNIOWorker"
serverExecutorThread-prefix = "NettyServerBizHandler"
shareBossWorker = false
clientSelectorThreadPrefix = "NettyClientSelector"
clientSelectorThreadSize = 1
clientWorkerThreadPrefix = "NettyClientWorkerThread"
# netty boss thread size,will not be used for UDT
bossThreadSize = 1
#auto default pin or 8
workerThreadSize = "default"
}
shutdown {
# when destroy server, wait seconds
wait = 3
}
serialization = "seata"
compressor = "none"
}
service {
#transaction service group mapping
vgroupMapping.istio_tx_group = "default"
#only support when registry.type=file, please don't set multiple addresses
#■■■■■■■■■■■■■ seata 地址设置 start ■■■■■■■■■■■■■
default.grouplist = "172.22.70.72:8091"
#■■■■■■■■■■■■■ seata 地址设置 end ■■■■■■■■■■■■■
#degrade, current not support
enableDegrade = false
#disable seata
disableGlobalTransaction = false
}
client {
rm {
asyncCommitBufferLimit = 10000
lock {
retryInterval = 10
retryTimes = 30
retryPolicyBranchRollbackOnConflict = true
}
reportRetryCount = 5
tableMetaCheckEnable = false
reportSuccessEnable = false
}
tm {
commitRetryCount = 5
rollbackRetryCount = 5
}
undo {
dataValidation = true
logSerialization = "jackson"
logTable = "undo_log"
}
log {
exceptionRate = 100
}
}
●log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<!-- ■■■■■ 要使这个配置生效,需要pom中排除掉spring-boot-starter-logging ■■■■■ -->
<!--全局参数-->
<Properties>
<!--
%d{yyyy-MM-dd HH:mm:ss.SSS} =>格式化时间 2020-01-21 14:03:53.858
%5p =>输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%t =>输出产生该日志事件的线程名
%c{1} =>输出日志信息所属的类目,通常就是所在类的全名
%L =>输出代码中的行号
%m =>输出代码中指定的消息,产生的日志具体信息
%n =>输出一个回车换行符,Windows平台为"\r\n",Unix平台为"\n"输出日志信息换行
-->
<Property name="pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} %5p %t %c{1}:%L - %m%n</Property>
<!-- ■■■日志输出文件夹【不同项目在同一个目录下时,用日志文件夹区分不同项目日志】 -->
<Property name="logDir">service2Logs/</Property>
</Properties>
<Loggers>
<Root level="INFO">
<AppenderRef ref="console"/>
<AppenderRef ref="asyncInfoLog"/>
<AppenderRef ref="asyncLogError"/>
</Root>
</Loggers>
<Appenders>
<!-- 定义输出到控制台 -->
<Console name="console" target="SYSTEM_OUT" follow="true">
<!--控制台只输出level及以上级别的信息-->
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>${pattern}</Pattern>
</PatternLayout>
</Console>
<!-- 同一来源的Appender可以定义多个RollingFile,定义按天存储日志 -->
<!-- INFO日志 -->
<RollingFile name="rolling_file_info" fileName="${logDir}/info_service2.log"
filePattern="${logDir}/info_service2_%d{yyyy-MM-dd}.log">
<Filters>
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<Pattern>${pattern}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<!-- 日志保留策略,配置只保留180天 -->
<DefaultRolloverStrategy>
<Delete basePath="${logDir}/" maxDepth="1">
<IfFileName glob="info_service2_*.log"/>
<IfLastModified age="180d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<!-- ERROR日志 -->
<RollingFile name="rolling_file_error" fileName="${logDir}/error_service2.log"
filePattern="${logDir}/error_service2_%d{yyyy-MM-dd}.log">
<Filters>
<ThresholdFilter level="FATAL" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<Pattern>${pattern}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<!-- 日志保留策略,配置只保留180天 -->
<DefaultRolloverStrategy>
<Delete basePath="${logDir}/" maxDepth="1">
<IfFileName glob="error_service2_*.log"/>
<IfLastModified age="180d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<Async name="asyncInfoLog" includeLocation="true">
<AppenderRef ref="rolling_file_info"/>
</Async>
<Async name="asyncLogError" includeLocation="true">
<AppenderRef ref="rolling_file_error"/>
</Async>
</Appenders>
</Configuration>
●registry.conf
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "file"
loadBalance = "RandomLoadBalance"
loadBalanceVirtualNodes = 10
nacos {
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = ""
cluster = "default"
username = ""
password = ""
}
eureka {
serviceUrl = "http://localhost:8761/eureka"
application = "default"
weight = "1"
}
redis {
serverAddr = "localhost:6379"
db = 0
password = ""
cluster = "default"
timeout = 0
}
zk {
cluster = "default"
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
}
consul {
cluster = "default"
serverAddr = "127.0.0.1:8500"
}
etcd3 {
cluster = "default"
serverAddr = "http://localhost:2379"
}
sofa {
serverAddr = "127.0.0.1:9603"
application = "default"
region = "DEFAULT_ZONE"
datacenter = "DefaultDataCenter"
cluster = "default"
group = "SEATA_GROUP"
addressWaitTime = "3000"
}
file {
name = "file.conf"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "file"
nacos {
serverAddr = "127.0.0.1:8848"
namespace = ""
group = "SEATA_GROUP"
username = ""
password = ""
}
consul {
serverAddr = "127.0.0.1:8500"
}
apollo {
appId = "seata-server"
apolloMeta = "http://192.168.1.204:8801"
namespace = "application"
apolloAccesskeySecret = ""
}
zk {
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
}
etcd3 {
serverAddr = "http://localhost:2379"
}
file {
name = "file.conf"
}
}
●pom.xml
<?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 https://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.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com</groupId>
<artifactId>istio-service2</artifactId>
<version>1.0</version>
<name>istio-service2</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- 分布式事务 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2.2.6.RELEASE</version>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.4.1</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
以上为Java项目部分。
以下为istio配置内容。
首先配置一个本项目的命名空间(istio-work-ns)
#创建命名空间
kubectl create ns istio-work-ns
将此命名空间设置为isito管理的命名空间(在此命名空间内创建的pod会自动配置sidecar)
#给命名空间打标签
kubectl label namespace istio-work-ns istio-injection=enabled
下面将3个服务打docker镜像,并可让k8s集群的3台机器都能访问到这个镜像。可以采用docker仓库的方式,也可以在一台机器上打镜像然后导出到其它机器上。
#制作docker镜像
docker build -t istio/service1:1.0 -f ./istioService1Dockerfile .
#导出镜像
docker save -o istioservice1.tar istio/service1:1.0
#导入镜像(集群中各个节点都要导入需部署镜像)
docker load < ./istioservice1.tar
以下是3个项目打docker镜像的配置文件
●istioClientDockerfile
#指定以openjdk:8-jre 为基础镜像,来构建此镜像,可以理解为运行的需要基础环境
FROM openjdk:8-jre
#WORKDIR指令用于指定容器的一个目录, 容器启动时执行的命令会在该目录下执行。
WORKDIR /
#将当前client.jar 复制到容器根目录下
ADD istio-client-1.0.jar istio-client-1.0.jar
#将依赖包 复制到容器根目录/libs下
#ADD libs /libs
#暴露容器端口为50051 Docker镜像告知Docker宿主机应用监听了50051端口
EXPOSE 8080
#容器启动时执行的命令
ENTRYPOINT ["java","-jar","/istio-client-1.0.jar"]
●istioService1Dockerfile
#指定以openjdk:8-jre 为基础镜像,来构建此镜像,可以理解为运行的需要基础环境
FROM openjdk:8-jre
#WORKDIR指令用于指定容器的一个目录, 容器启动时执行的命令会在该目录下执行。
WORKDIR /
#将当前client.jar 复制到容器根目录下
ADD istio-service1-1.0.jar istio-service1-1.0.jar
#将依赖包 复制到容器根目录/libs下
#ADD libs /libs
#暴露容器端口为50051 Docker镜像告知Docker宿主机应用监听了50051端口
EXPOSE 8081
#容器启动时执行的命令
ENTRYPOINT ["java","-jar","/istio-service1-1.0.jar"]
●istioService2Dockerfile
#指定以openjdk:8-jre 为基础镜像,来构建此镜像,可以理解为运行的需要基础环境
FROM openjdk:8-jre
#WORKDIR指令用于指定容器的一个目录, 容器启动时执行的命令会在该目录下执行。
WORKDIR /
#将当前client.jar 复制到容器根目录下
ADD istio-service2-1.0.jar istio-service2-1.0.jar
#将依赖包 复制到容器根目录/libs下
#ADD libs /libs
#暴露容器端口为50051 Docker镜像告知Docker宿主机应用监听了50051端口
EXPOSE 8082
#容器启动时执行的命令
ENTRYPOINT ["java","-jar","/istio-service2-1.0.jar"]
以下是3个项目的pod和service配置
●client.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: istioclient
namespace: istio-work-ns
labels:
app: istioclient
spec:
replicas: 1
selector:
matchLabels:
app: istioclient
template:
metadata:
labels:
app: istioclient
spec:
containers:
- name: istioclient
image: istio/client:1.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: istioclient
namespace: istio-work-ns
spec:
clusterIP: 10.108.232.10
ports:
- port: 8080
targetPort: 8080
selector:
app: istioclient
●service1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: istioservice1
namespace: istio-work-ns
labels:
app: istioservice1
spec:
replicas: 1
selector:
matchLabels:
app: istioservice1
template:
metadata:
labels:
app: istioservice1
spec:
containers:
- name: istioservice1
image: istio/service1:1.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8081
---
apiVersion: v1
kind: Service
metadata:
name: istioservice1
namespace: istio-work-ns
spec:
clusterIP: 10.108.232.20
ports:
- port: 8081
targetPort: 8081
selector:
app: istioservice1
●service2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: istioservice2
namespace: istio-work-ns
labels:
app: istioservice2
spec:
replicas: 1
selector:
matchLabels:
app: istioservice2
template:
metadata:
labels:
app: istioservice2
spec:
containers:
- name: istioservice2
image: istio/service2:1.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8082
---
apiVersion: v1
kind: Service
metadata:
name: istioservice2
namespace: istio-work-ns
spec:
clusterIP: 10.108.232.30
ports:
- port: 8082
targetPort: 8082
selector:
app: istioservice2
配置本项目的入口(istio的ingress gateway)
●gateway-test.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: alp-gateway
namespace: istio-work-ns
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: alp-vs
namespace: istio-work-ns
spec:
hosts:
- "*"
gateways:
- alp-gateway
http:
- match:
- uri:
prefix: /test
route:
- destination:
host: istioclient
port:
number: 8080
查看ingress gateway的80端口的映射地址
kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.103.204.76 <pending> 15020:31965/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:31388/TCP,15030:31011/TCP,15031:30711/TCP,15032:30715/TCP,15443:32497/TCP 4d2h
确认服务部署成功。访问地址:http://192.168.42.131:31380/test/getTest1
以上为采用istio的ingress gateway方式开放服务。
还可以采用k8s的ingress方式开放服务。
●ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-demo
namespace: istio-work-ns
spec:
rules:
- host: k8s.test
http:
paths:
- path: /
backend:
serviceName: istioclient
servicePort: 8080
访问此服务需要在本地hosts文件中追加k8s.test配置
C:\Windows\System32\drivers\etc\hosts
192.168.42.131 k8s.test
访问地址http://k8s.test/test/getTest1,确认项目发布成功。
更多推荐
所有评论(0)