# Java

# jdk,jre linux环境变量安装(1.8)

1、下载jdk

wget https://ligl.top/tool/java/jdk-8u341-linux-x64.tar.gz
1

2、解压压缩包

tar -zxvf 压缩包文件
1

3、编辑环境变量

vim /etc/profile
1
export JAVA_HOME=<解压到的路径>
export JRE_HOME=${JAVA_HOME}/jre
export PATH=${JAVA_HOME}/bin:$PATH
export CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar
1
2
3
4

4、重新加载环境变量

source /etc/profile
1

# SpringBoot

# 跨域(搞了一天多.....)

这个值为true,代表发送Ajax请求的时候,携带第三方Cookie。 这是个非常危险的动作,因此,必须后端明确的指定允许哪些域名能够访问,不能设置为通用的 *,如果为false可以用 * 如果非要后端解决的话 就从过滤器里读取出来 Origin 然后设置到响应头里,gateway不会自动优化,需要手动处理

// 前置函数:在每次认证函数之前执行
saReactorFilter.setBeforeAuth(obj -> {
  // 获得客户端domain
  SaRequest request = SaHolder.getRequest();
  String origin = request.getHeader("Origin");
  if (origin == null) {
    origin = request.getHeader("Referer");
  }
  // ---------- 设置跨域响应头 ----------
  // todo 建议不要写 * 代替,如果请求前端 请求时 withCredentials 设置为true, * 是无效的必须写具体的内容....
  SaHolder.getResponse()
  // 允许指定域访问跨域资源
  .setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, origin)
  // 允许客户端携带跨域cookie,此时origin值不能为“*”,只能为指定单一域名
  .setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true")
  // 允许所有请求方式
  .setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTIONS")
  // 有效时间
  .setHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "3600")
  // 允许的header参数
  .setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "Token,Authorization,BaToken,Content-Type,Accept,Origin,Accept-Encoding,Accept-Language,Cookie,User-Agent,Cache-Control,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With");
  // 如果是预检请求,则立即返回到前端
  SaRouter.match(SaHttpMethod.OPTIONS)
  .free(r -> {
    log.info("OPTIONS 预检请求,不做处理.....");
  })
  .back();
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

这里设置 * 可以是因为 这是Spring的跨域处理方案,你虽然写的是 * ,但是它底层帮你自动优化了 他检测到你 aTTowCredentials(true) 了,就自动给你优化了

@Configuration
public class WebConfig implements WebMvcConfigurer {

  @Override
  public void addCorsMappings(CorsRegistry registry) {
    System.out.println(">>>>>>>>>>>>>>>加载mvcCors跨域配置");
    registry.addMapping("/**")
    .allowedOriginPatterns("*")
    .allowCredentials(true)
    .allowedMethods("*")
    .maxAge(3600);
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 配置文件注入

@Value注解在需注入的属性之上
@value格式为 @Value(“${key}”)

1
2
3

# 编写配置类

@Data
@Component
// prefix 配置前搓
@ConfigurationProperties(prefix = "dict")
1
2
3
4

# 注入String

属性是驼峰,在写yml是要用 - 标注,提示不使用-也是可以正常注入

private String accessKey;
1
dict:
  access-key: Ev-
  secret-key: 411111
  bucket: iles
  doumain: tware.cn
  dir: qiniu_data
  year: 2022

1
2
3
4
5
6
7
8

# 注入Map

private Map<String,String> section;
1
# 前搓
dict:
  # java类中的属性名称
  section:
    # map的key和val
    G001: 东南
    G002:G003:
1
2
3
4
5
6
7
8
9

# 注入List

private List<String> serList = new ArrayList<String>();
1
# 前搓
dict:
  # java类中的属性名称
  serList:
    # list 元素
    - G001东南
    - G002新
    - G003琶

1
2
3
4
5
6
7
8
9

拓展 注入list<Map<String,String>>

private List<Map<String, String>> robot = new ArrayList<>();
1
robot:
- name: robot1
  token: token1
- name: robot2
  token: token2

1
2
3
4
5
6

# 自动提示

<!--把项目中的springboot自定义属性配置类生成一个元素数据文件,这个文件可以生成以后
    在未来的配置文件中,我们就达到和官方一致效果,可以自动提示-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
        </dependency>

1
2
3
4
5
6
7
8

# k8s通用部署文件

Dockerfile

FROM dkqrfrdj.mirror.aliyuncs.com/library/openjdk:8
MAINTAINER LiGuangLong
COPY target/*.jar /code/app.jar
WORKDIR /code
ENV TZ=Asia/Shanghai
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
ENTRYPOINT ["java","-server","-Xms256M","-Xmx256M","-Dfile.encoding=UTF-8","-Duser.timezone=GMT+08","-jar","app.jar"]
1
2
3
4
5
6
7
FROM dkqrfrdj.mirror.aliyuncs.com/library/nginx
MAINTAINER LiGuangLong
ENV TZ=Asia/Shanghai
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
COPY dist/  /usr/share/nginx/html/
COPY nginx.conf /etc/nginx/nginx.conf
1
2
3
4
5
6

nginx.conf


user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format json '{"dtTime":"$time_iso8601",'
					'"content":"FwIp=>$remote_addr,Uri=>$uri,Method=>$request_method,Query=>$query_string,Body=>$request_body,Status=>$status,size=>$body_bytes_sent,request_time=>$request_time",'
					'"serverName":"$server_addr",'
					'"method":"$http_user_agent",'
					'"appName":"Nginx"'
					'}';
    access_log  /var/log/nginx/access.log  json;

	server_tokens off;
    keepalive_timeout  65;




	# 注意⚠️:如果使用了多个nginx通过proxy_pass进行代理,如果上层没有设置压缩参数,是不生效的,

	#数据0拷贝
	sendfile on;
	# 开启gzip
	gzip  on;
	# 无条件压缩所有结果数据
	gzip_proxied any;
	# 设置压缩所需要的缓冲区大小
	gzip_buffers 4 16k;
	# 压缩级别1-9,越大压缩率越高,同时消耗cpu资源也越多,建议设置在4左右。
	gzip_comp_level 6;
	# 需要压缩哪些响应类型的资源,缺少的类型自己补。
	gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
	# 配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
	gzip_disable "msie6";
	# 是否添加“Vary: Accept-Encoding”响应头,
	gzip_vary on;
	# 设置gzip压缩针对的HTTP协议版本,没做负载的可以不用
	gzip_http_version 1.1;

	server {
		listen       13009;
		server_name  localhost;

		charset 'utf-8';

		# 前搓配置方式一
		# base配置,如果前端添加了前搓,需要修改本文件中location匹配路径与前搓相同 如:location /blog 则访问路径:http://172.30.196.141:13009/blog
		# 前搓配置方式二(建议使用)
		# 如果前端项目使用必须使用80端口访问多个前端项目则,前搓需要在80Nginx中配置前搓,并配置转发 proxy_pass 到本容器端口,本文件中的location不用修改

		location / {
			# 注意⚠️:如果vue-router使用的是history模式,try_files $uri $uri/ /index.html;  非常重要!!!
			# 如果使用了hash模式,可以省略这个
			# try_files $uri $uri/ /index.html;
			alias   /usr/share/nginx/html/;
		}

		error_page   500 502 503 504  /50x.html;
		location = /50x.html {
			root   /usr/share/nginx/html;
		}
	}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

deploy.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: ${APP_NAME}
  name: ${APP_NAME}
  # 部署的命名空间
  namespace: ${NAME_SPACE}   
spec:
  # pod副本
  replicas: 1
  selector:
    matchLabels:
      app: ${APP_NAME}
  template:
    metadata:
      labels:
        app: ${APP_NAME}
    spec:
      containers:
        - image: ${REGISTRY}/${DOCKERHUB_NAMESPACE}/${APP_NAME}:SNAPSHOT-${BUILD_NUMBER}
          imagePullPolicy: Always
          name: app
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: ${APP_NAME}
  name: ${APP_NAME}
  namespace: ${NAME_SPACE}
spec:
  ports:
    - name: http
      # 服务端口
      port: ${APP_PORT}
      protocol: TCP
      # 要转发到pod的端口
      targetPort: ${APP_PORT}
  selector:
    # 用来指定service将路由流量转发到那些pod
    app: ${APP_NAME}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

jenkinsfile

maven项目

pipeline {
  agent {
    node {
      label 'maven'
    }
  }
  stages {
    stage('拉取代码') {
      agent none
      steps {
        container('maven') {
          git(url: 'https://gitlab.eaglesoftware.cn/eagle_highway_brain/server-group/portal_management_server.git', credentialsId: 'gitlab-lgl', branch: 'master', changelog: true, poll: false)
          sh 'ls -all'
        }
      }
    }
    stage('编译项目') {
      agent none
      steps {
        container('maven') {
          sh 'mvn clean package -Dmaven.test.skip=true -f  pom.xml'
        }
      }
    }
    stage('构建镜像') {
      agent none
      steps {
        container('maven') {
          // 由于这里指定的打包路径,dockerfile中的引用资源路径写相对路径就可以了
          sh 'docker build -t $APP_NAME:latest -f ${APP_PATH}/Dockerfile ${APP_PATH}'
        }
      }
    }
     stage('推送镜像') {
      agent none
      steps {
        container('maven') {
          withCredentials([usernamePassword(credentialsId : 'harbor-id' ,passwordVariable : 'DOCKER_PWD_VAR' ,usernameVariable : 'DOCKER_USER_VAR' ,)]) {
            sh 'echo "$DOCKER_PWD_VAR" | docker login $REGISTRY -u "$DOCKER_USER_VAR" --password-stdin'
            sh 'docker tag $APP_NAME:latest $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER'
            sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER'
          }
        }
      }
    }
    stage('部署应用') {
      agent none
      steps {
        container('maven') {
          withCredentials([kubeconfigFile(credentialsId: "$KUBECONFIG_CREDENTIAL_ID", variable: 'KUBECONFIG')]) {
            sh 'envsubst \'${REGISTRY},${DOCKERHUB_NAMESPACE},${BUILD_NUMBER},${APP_PORT},${NAME_SPACE},${APP_NAME}\' < ${APP_PATH}/deploy.yml > ${APP_PATH}/deploy2.yml'
            sh 'kubectl apply -f ${APP_PATH}/deploy2.yml'
          }
        }
      }
    }
  }
  environment {
    KUBECONFIG_CREDENTIAL_ID = 'k8s-kubeconfig'
    REGISTRY = '10.44.111.34:9800'
    DOCKERHUB_NAMESPACE = 'eagle'
    NAME_SPACE = 'yitihua'
    APP_NAME = 'yth-auth'    
    APP_PATH = 'single-auth'
    APP_PORT = 80
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

node项目

pipeline {
  agent {
    kubernetes {
      inheritFrom 'nodejs base'
      containerTemplate {
        name 'nodejs'
        image 'node:16.16.0'
      }
    }
  }
  stages {
    stage('拉取代码') {
      agent none
      steps {
        git(url: 'https://gitlab.eaglesoftware.cn/eagle_highway_brain/pc_page_group/portal_management_page.git', credentialsId: 'gitlab-certificate', branch: 'master', changelog: true, poll: false)
        sh 'ls -all'
      }
    }
    stage('打包项目') {
      agent none
      steps {
        container('nodejs') {
          sh 'node -v'
          sh 'npm cache clear --force'
          sh 'npm config set registry https://registry.npm.taobao.org/'
          sh 'npm install --prefix roadAdmin/'
          sh 'npm run build:dev_eagle --prefix roadAdmin/'
          sh 'ls'
        }
      }
    }
    stage('构建镜像') {
      agent none
      steps {
        container('base') {
          sh 'docker build -t $APP_NAME:latest -f ./roadAdmin/Dockerfile roadAdmin'
        }
      }
    }

    stage('推送镜像') {
      agent none
      steps {
        container('base') {
          withCredentials([usernamePassword(credentialsId : 'harbor-id' ,passwordVariable : 'DOCKER_PWD_VAR' ,usernameVariable : 'DOCKER_USER_VAR' ,)]) {
            sh 'echo "$DOCKER_PWD_VAR" | docker login $REGISTRY -u "$DOCKER_USER_VAR" --password-stdin'
            sh 'docker tag $APP_NAME:latest $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER'
            sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER'
          }
        }
      }
    }
    stage('部署应用') {
      agent none
      steps {
        container('base') {
          withCredentials([kubeconfigFile(credentialsId: "$KUBECONFIG_CREDENTIAL_ID", variable: 'KUBECONFIG')]) {
            sh 'envsubst \'${REGISTRY},${DOCKERHUB_NAMESPACE},${BUILD_NUMBER},${NAME_SPACE},${APP_PORT},${APP_NAME}\' < roadAdmin/deploy.yml > roadAdmin/deploy2.yml'
            sh 'kubectl apply -f roadAdmin/deploy2.yml'
          }
        }
      }
    }

  }
  environment {
    KUBECONFIG_CREDENTIAL_ID = 'k8s-kubeconfig'
    REGISTRY = '10.44.111.34:9800'
    DOCKERHUB_NAMESPACE = 'eagle'
    NAME_SPACE = 'yitihua' 
    APP_NAME = 'mh-vue'
    APP_PORT = 80
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
Last Updated: 1/17/2024, 2:34:03 PM